diff --git a/src/backend/base.js b/src/backend/base.js index 1b06dc01..94cccf4f 100644 --- a/src/backend/base.js +++ b/src/backend/base.js @@ -99,6 +99,32 @@ this.recline.Backend = this.recline.Backend || {}; query: function(model, queryObj) { }, + // ### _makeRequest + // + // Just $.ajax but in any headers in the 'headers' attribute of this + // Backend instance. Example: + // + //
+ // var jqxhr = this._makeRequest({
+ // url: the-url
+ // });
+ //
+ _makeRequest: function(data) {
+ var headers = this.get('headers');
+ var extras = {};
+ if (headers) {
+ extras = {
+ beforeSend: function(req) {
+ _.each(headers, function(value, key) {
+ req.setRequestHeader(key, value);
+ });
+ }
+ };
+ }
+ var data = _.extend(extras, data);
+ return $.ajax(data);
+ },
+
// convenience method to convert simple set of documents / rows to a QueryResult
_docsToQueryResult: function(rows) {
var hits = _.map(rows, function(row) {
diff --git a/src/backend/elasticsearch.js b/src/backend/elasticsearch.js
index 03448277..546c0c8a 100644
--- a/src/backend/elasticsearch.js
+++ b/src/backend/elasticsearch.js
@@ -6,37 +6,39 @@ this.recline.Backend = this.recline.Backend || {};
//
// Connecting to [ElasticSearch](http://www.elasticsearch.org/).
//
- // To use this backend ensure your Dataset has one of the following
- // attributes (first one found is used):
+ // Usage:
+ //
+ //
+ // var backend = new recline.Backend.ElasticSearch({
+ // // optional as can also be provided by Dataset/Document
+ // url: {url to ElasticSearch endpoint i.e. ES 'type/table' url - more info below}
+ // // optional
+ // headers: {dict of headers to add to each request}
+ // });
+ //
+ // @param {String} url: url for ElasticSearch type/table, e.g. for ES running
+ // on localhost:9200 with index // twitter and type tweet it would be:
+ //
+ // http://localhost:9200/twitter/tweet
+ //
+ // This url is optional since the ES endpoint url may be specified on the the
+ // dataset (and on a Document by the document having a dataset attribute) by
+ // having one of the following (see also `_getESUrl` function):
//
//
// elasticsearch_url
// webstore_url
// url
//
- //
- // This should point to the ES type url. E.G. for ES running on
- // localhost:9200 with index twitter and type tweet it would be
- //
- // http://localhost:9200/twitter/tweet
my.ElasticSearch = my.Base.extend({
__type__: 'elasticsearch',
readonly: false,
- _getESUrl: function(dataset) {
- var out = dataset.get('elasticsearch_url');
- if (out) return out;
- out = dataset.get('webstore_url');
- if (out) return out;
- out = dataset.get('url');
- return out;
- },
sync: function(method, model, options) {
var self = this;
if (method === "read") {
if (model.__type__ == 'Dataset') {
- var base = self._getESUrl(model);
- var schemaUrl = base + '/_mapping';
- var jqxhr = $.ajax({
+ var schemaUrl = self._getESUrl(model) + '/_mapping';
+ var jqxhr = this._makeRequest({
url: schemaUrl,
dataType: 'jsonp'
});
@@ -57,36 +59,75 @@ this.recline.Backend = this.recline.Backend || {};
return dfd.promise();
} else if (model.__type__ == 'Document') {
var base = this._getESUrl(model.dataset) + '/' + model.id;
- return $.ajax({
+ return this._makeRequest({
url: base,
dataType: 'json'
});
}
} else if (method === 'update') {
if (model.__type__ == 'Document') {
- var data = JSON.stringify(model.toJSON());
- var base = this._getESUrl(model.dataset);
- if (model.id) {
- base += '/' + model.id;
- }
- return $.ajax({
- url: base,
- type: 'POST',
- data: data,
- dataType: 'json'
- });
+ return this.upsert(model.toJSON(), this._getESUrl(model.dataset));
}
} else if (method === 'delete') {
if (model.__type__ == 'Document') {
- var base = this._getESUrl(model.dataset) + '/' + model.id;
- return $.ajax({
- url: base,
- type: 'DELETE',
- dataType: 'json'
- });
+ var url = this._getESUrl(model.dataset);
+ return this.delete(model.id, url);
}
}
},
+
+ // ### upsert
+ //
+ // create / update a document to ElasticSearch backend
+ //
+ // @param {Object} doc an object to insert to the index.
+ // @param {string} url (optional) url for ElasticSearch endpoint (if not
+ // defined called this._getESUrl()
+ upsert: function(doc, url) {
+ var data = JSON.stringify(doc);
+ url = url ? url : this._getESUrl();
+ if (doc.id) {
+ url += '/' + doc.id;
+ }
+ return this._makeRequest({
+ url: url,
+ type: 'POST',
+ data: data,
+ dataType: 'json'
+ });
+ },
+
+ // ### delete
+ //
+ // Delete a document from the ElasticSearch backend.
+ //
+ // @param {Object} id id of object to delete
+ // @param {string} url (optional) url for ElasticSearch endpoint (if not
+ // provided called this._getESUrl()
+ delete: function(id, url) {
+ url = url ? url : this._getESUrl();
+ url += '/' + id;
+ return this._makeRequest({
+ url: url,
+ type: 'DELETE',
+ dataType: 'json'
+ });
+ },
+
+ // ### _getESUrl
+ //
+ // get url to ElasticSearch endpoint (see above)
+ _getESUrl: function(dataset) {
+ if (dataset) {
+ var out = dataset.get('elasticsearch_url');
+ if (out) return out;
+ out = dataset.get('webstore_url');
+ if (out) return out;
+ out = dataset.get('url');
+ return out;
+ }
+ return this.get('url');
+ },
_normalizeQuery: function(queryObj) {
var out = queryObj.toJSON ? queryObj.toJSON() : _.extend({}, queryObj);
if (out.q !== undefined && out.q.trim() === '') {
@@ -123,7 +164,7 @@ this.recline.Backend = this.recline.Backend || {};
var queryNormalized = this._normalizeQuery(queryObj);
var data = {source: JSON.stringify(queryNormalized)};
var base = this._getESUrl(model);
- var jqxhr = $.ajax({
+ var jqxhr = this._makeRequest({
url: base + '/_search',
data: data,
dataType: 'jsonp'