From b0bf06c52e98253d95e3e14a06946b8d20760fd9 Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Sat, 14 Apr 2012 10:00:17 +0100 Subject: [PATCH] [#34,query,backend/memory][s]: memory backend support query string (q parameter). --- src/backend/memory.js | 46 ++++++++++++++++++++++++++++++++++++------- test/backend.test.js | 14 +++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/backend/memory.js b/src/backend/memory.js index 6ae7ae13..49f03087 100644 --- a/src/backend/memory.js +++ b/src/backend/memory.js @@ -117,13 +117,9 @@ this.recline.Backend = this.recline.Backend || {}; var out = {}; var numRows = queryObj.size; var start = queryObj.from; - results = this.datasets[model.id].documents; - _.each(queryObj.filters, function(filter) { - results = _.filter(results, function(doc) { - var fieldId = _.keys(filter.term)[0]; - return (doc[fieldId] == filter.term[fieldId]); - }); - }); + var results = this.datasets[model.id].documents; + results = this._applyFilters(results, queryObj); + results = this._applyFreeTextQuery(model, results, queryObj); // not complete sorting! _.each(queryObj.sort, function(sortObj) { var fieldName = _.keys(sortObj)[0]; @@ -141,6 +137,42 @@ this.recline.Backend = this.recline.Backend || {}; return dfd.promise(); }, + // in place filtering + _applyFilters: function(results, queryObj) { + _.each(queryObj.filters, function(filter) { + results = _.filter(results, function(doc) { + var fieldId = _.keys(filter.term)[0]; + return (doc[fieldId] == filter.term[fieldId]); + }); + }); + return results; + }, + + // we OR across fields but AND across terms in query string + _applyFreeTextQuery: function(dataset, results, queryObj) { + if (queryObj.q) { + var terms = queryObj.q.split(' '); + results = _.filter(results, function(rawdoc) { + var matches = true; + _.each(terms, function(term) { + var foundmatch = false; + dataset.fields.each(function(field) { + var value = rawdoc[field.id].toString(); + // TODO regexes? + foundmatch = foundmatch || (value === term); + // TODO: early out (once we are true should break to spare unnecessary testing) + // if (foundmatch) return true; + }); + matches = matches && foundmatch; + // TODO: early out (once false should break to spare unnecessary testing) + // if (!matches) return false; + }); + return matches; + }); + } + return results; + }, + _computeFacets: function(documents, queryObj) { var facetResults = {}; if (!queryObj.facets) { diff --git a/test/backend.test.js b/test/backend.test.js index 9b5453d3..ee298194 100644 --- a/test/backend.test.js +++ b/test/backend.test.js @@ -79,6 +79,20 @@ test('Memory Backend: query sort', function () { }); }); +test('Memory Backend: query string', function () { + var dataset = makeBackendDataset(); + dataset.fetch(); + dataset.query({q: 'UK'}).then(function() { + equal(dataset.currentDocuments.length, 3); + deepEqual(dataset.currentDocuments.pluck('country'), ['UK', 'UK', 'UK']); + }); + + dataset.query({q: 'UK 6'}).then(function() { + equal(dataset.currentDocuments.length, 1); + deepEqual(dataset.currentDocuments.models[0].id, 1); + }); +}); + test('Memory Backend: filters', function () { var dataset = makeBackendDataset(); dataset.queryState.addTermFilter('country', 'UK');