diff --git a/lib/api3/storage/mongoCollection/utils.js b/lib/api3/storage/mongoCollection/utils.js index a2f7b16520c..a7ee4e55e09 100644 --- a/lib/api3/storage/mongoCollection/utils.js +++ b/lib/api3/storage/mongoCollection/utils.js @@ -27,6 +27,7 @@ function normalizeDoc (doc) { */ function parseFilter (filterDef, logicalOperator, onlyValid) { let filter = { }; + if (!filterDef) return filter; @@ -39,56 +40,57 @@ function parseFilter (filterDef, logicalOperator, onlyValid) { for (const itemDef of filterDef) { let item; + // Check if a query is already started for given field + if (!filter.hasOwnProperty(itemDef.field)) { + filter[itemDef.field] = {}; + } + switch (itemDef.operator) { case 'eq': - item = itemDef.value; + filter[itemDef.field]['$eq'] = itemDef.value; break; case 'ne': - item = { $ne: itemDef.value }; + filter[itemDef.field]['$ne'] = itemDef.value; break; case 'gt': - item = { $gt: itemDef.value }; + filter[itemDef.field]['$gt'] = itemDef.value; break; case 'gte': - item = { $gte: itemDef.value }; + filter[itemDef.field]['$gte'] = itemDef.value; break; case 'lt': - item = { $lt: itemDef.value }; + filter[itemDef.field]['$lt'] = itemDef.value; break; case 'lte': - item = { $lte: itemDef.value }; + filter[itemDef.field]['$lte'] = itemDef.value; break; case 'in': - item = { $in: itemDef.value.toString().split('|') }; + filter[itemDef.field]['$in'] = itemDef.value.toString().split('|'); break; case 'nin': - item = { $nin: itemDef.value.toString().split('|') }; + filter[itemDef.field]['$nin'] = itemDef.value.toString().split('|'); break; case 're': - item = { $regex: itemDef.value.toString() }; + filter[itemDef.field]['$regex'] = itemDef.value.toString(); break; default: throw new Error('Unsupported or missing filter operator ' + itemDef.operator); - } + } // switch (itemDef.operator) if (logicalOperator === 'or') { - let clause = { }; - clause[itemDef.field] = item; - clauses.push(clause); - } - else { - filter[itemDef.field] = item; + clauses.push(filter); + filter = { }; } - } + } // for (const itemDef of filterDef) if (logicalOperator === 'or') { filter = { $or: clauses }; diff --git a/tests/api3.search.test.js b/tests/api3.search.test.js index aeafc84630c..826b1c15859 100644 --- a/tests/api3.search.test.js +++ b/tests/api3.search.test.js @@ -204,6 +204,83 @@ describe('API3 SEARCH', function() { }); + it('should filter entries', async () => { + let res = await self.instance.get(`${self.url}?sgv$eq=${testConst.SAMPLE_ENTRIES[4].sgv}`, self.jwt.read) + .expect(200); + + res.body.status.should.equal(200); + const results = res.body.result; + const length = results.length; + length.should.be.aboveOrEqual(1); + + for (let i in results) { + results[i].sgv.should.equal(testConst.SAMPLE_ENTRIES[4].sgv); + } + }); + + + it('should filter entries by multiple parameters', async () => { + let res = await self.instance.get(`${self.url}?date$gt=${testConst.SAMPLE_ENTRIES[2].date}&sgv$lte=179`, self.jwt.read) + .expect(200); + + res.body.status.should.equal(200); + const results = res.body.result; + const length = results.length; + length.should.be.aboveOrEqual(5); + + for (let i in results) { + results[i].date.should.be.aboveOrEqual(testConst.SAMPLE_ENTRIES[2].date); + results[i].sgv.should.be.belowOrEqual(179); + } + }); + + + it('should filter entries by ISO8601 date', async () => { + let res = await self.instance.get(`${self.url}?date$eq=2017-04-09T06:18:50`, self.jwt.read) + .expect(200); + + res.body.status.should.equal(200); + const results = res.body.result; + const length = results.length; + length.should.be.aboveOrEqual(1); + + for (let i in results) { + results[i].date.should.equal(1491718730000.0); + } + }); + + + it('should filter entries by ISO8601 date with timezone', async () => { + let res = await self.instance.get(`${self.url}?date$eq=2017-04-09T12:18:50%2B06:00`, self.jwt.read) + .expect(200); + + res.body.status.should.equal(200); + const results = res.body.result; + const length = results.length; + length.should.be.aboveOrEqual(1); + + for (let i in results) { + results[i].date.should.equal(1491718730000.0); + } + }); + + + it('should filter entries by date range', async () => { + let res = await self.instance.get(`${self.url}?date$gt=1491719030000&date$lt=1491719930000`, self.jwt.read) + .expect(200); + + res.body.status.should.equal(200); + const results = res.body.result; + const length = results.length; + length.should.be.aboveOrEqual(2); + + for (let i in results) { + results[i].date.should.be.above(1491719030000.0); + results[i].date.should.be.below(1491719930000.0); + } + }); + + it('should skip documents', async () => { let res = await self.instance.get(`${self.url}?sort=date&limit=8`, self.jwt.read) .expect(200);