From 6ba8c82408e94e3eaa483b5614628a83172a3227 Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Sun, 1 Apr 2012 13:51:15 +0100 Subject: [PATCH] [#62,facets][s]: partially working faceting with elasticsearch. --- src/backend/elasticsearch.js | 3 +++ src/model.js | 29 +++++++++++++++++++++++++---- test/model.test.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/backend/elasticsearch.js b/src/backend/elasticsearch.js index a0f960e6..c2e9331e 100644 --- a/src/backend/elasticsearch.js +++ b/src/backend/elasticsearch.js @@ -98,6 +98,9 @@ this.recline.Backend = this.recline.Backend || {}; hit._source.id = hit._id; } }) + if (results.facets) { + results.hits.facets = results.facets; + } dfd.resolve(results.hits); }); return dfd.promise(); diff --git a/src/model.js b/src/model.js index e102f932..09b9052f 100644 --- a/src/model.js +++ b/src/model.js @@ -27,6 +27,7 @@ my.Dataset = Backbone.Model.extend({ this.docCount = null; this.queryState = new my.Query(); this.queryState.bind('change', this.query); + this.facets.bind('all', this.query); }, // ### query @@ -39,11 +40,15 @@ my.Dataset = Backbone.Model.extend({ // Resulting DocumentList are used to reset this.currentDocuments and are // also returned. query: function(queryObj) { - this.trigger('query:start'); var self = this; - this.queryState.set(queryObj); + this.trigger('query:start'); + // HACK: query gets called on event changes and it appears that in those cases the type of event gets passed as first argument. The following handles those cases. + if (typeof(queryObj) != 'object') { + queryObj = null; + } + var actualQuery = self._prepareQuery(queryObj); var dfd = $.Deferred(); - this.backend.query(this, this.queryState.toJSON()).done(function(queryResult) { + this.backend.query(this, actualQuery).done(function(queryResult) { self.docCount = queryResult.total; var docs = _.map(queryResult.hits, function(hit) { var _doc = new my.Document(hit._source); @@ -52,6 +57,11 @@ my.Dataset = Backbone.Model.extend({ return _doc; }); self.currentDocuments.reset(docs); + if (queryResult.facets) { + _.each(queryResult.facets, function(facetResult, facetId) { + self.facets.get(facetId).set({result: facetResult}); + }); + } self.trigger('query:done'); dfd.resolve(self.currentDocuments); }) @@ -62,6 +72,17 @@ my.Dataset = Backbone.Model.extend({ return dfd.promise(); }, + _prepareQuery: function(newQueryObj) { + if (newQueryObj) { + this.queryState.set(newQueryObj); + } + var out = this.queryState.toJSON(); + _.each(this.facets.toJSON(), function(facet) { + out.facets[facet.id] = facet.query; + }); + return out; + }, + toTemplateJSON: function() { var data = this.toJSON(); data.docCount = this.docCount; @@ -137,7 +158,7 @@ my.FacetList = Backbone.Collection.extend({ model: my.Facet, addFacet: function(fieldId) { // Assume id and fieldId should be the same (TODO: this need not be true if we want to add two different type of facets on same field) - if (fieldId in this) { + if (this.include(fieldId)) { return; } // TODO: utilize field info to determine facet type ?? diff --git a/test/model.test.js b/test/model.test.js index 61587bd9..c029756b 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -1,6 +1,9 @@ (function ($) { module("Model"); +// ================================= +// Field + test('Field: basics', function () { var field = new recline.Model.Field({ id: 'x' @@ -35,6 +38,10 @@ test('Field: basics', function () { equal('XX', out[0].label); }); + +// ================================= +// Dataset + test('Dataset', function () { var meta = {id: 'test', title: 'xyz'}; var dataset = new recline.Model.Dataset(meta); @@ -43,6 +50,28 @@ test('Dataset', function () { equal(out.fields.length, 2); }); +test('Dataset _prepareQuery', function () { + var meta = {id: 'test', title: 'xyz'}; + var dataset = new recline.Model.Dataset(meta); + + var out = dataset._prepareQuery(); + var exp = new recline.Model.Query().toJSON(); + deepEqual(out, exp); + + var fieldId = 'abc'; + dataset.facets.addFacet(fieldId); + + var out = dataset._prepareQuery(); + var exp = new recline.Model.Query().toJSON(); + exp.facets = {}; + exp.facets[fieldId] = { terms: {field: fieldId} }; + deepEqual(out, exp); +}); + + +// ================================= +// Facet + test('Facet', function () { var facets = new recline.Model.FacetList(); facets.addFacet('xyz');