Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 62 additions & 40 deletions lib/elasticsearchHandler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"use strict";
var ElasticsearchStore = module.exports = function ElasticsearchStore() { };

var async = require("async");
var debug = require("debug")("jsonApi:store:elasticsearch");
Expand All @@ -9,46 +8,53 @@ var _ = {
};


var ElasticsearchStore = module.exports = function ElasticsearchStore(config) {
this.config = _.assign({
host: "localhost:9200",
index: "jsonapi"
}, config);
};

ElasticsearchStore.prototype.ready = false;

ElasticsearchStore.prototype._buildQuery = function(request) {
var self = this;

var queryString = "type:" + request.params.type;
if (!request.params.filter) return queryString;
if (request.params.filter) {
var filterString = Object.keys(request.params.filter).map(function (attribute) {
var attributeConfig = self.resourceConfig.attributes[attribute];
// If the filter attribute doens't exist, skip it
if (!attributeConfig) return null;

queryString = "(" + queryString + ")";
var filterString = Object.keys(request.params.filter).map(function(attribute) {
var attributeConfig = self.resourceConfig.attributes[attribute];
// If the filter attribute doens't exist, skip it
if (!attributeConfig) return null;
var values = request.params.filter[attribute];
if (!values) return null;

var values = request.params.filter[attribute];
if (!values) return null;
// Relationships need to be queried via .id
if (attributeConfig._settings) {
attribute += ".id";
// Filters on nested resources should be skipped
if (values instanceof Object) return null;
}

// Relationships need to be queried via .id
if (attributeConfig._settings) {
attribute += ".id";
// Filters on nested resources should be skipped
if (values instanceof Object) return null;
}
// Coerce values to an array to simplify the logic
values = [].concat(values);
values = values.map(function (value) {
if (value[0] === ":" || (value[0] === "~")) return value.substring(1);
return value;
}).join(" OR ");

// Coerce values to an array to simplify the logic
values = [].concat(values);
values = values.map(function(value) {
if (value[0] === ":" || (value[0] === "~")) return value.substring(1);
return value;
}).join(" OR ");
return attribute + ":(" + values + ")";
}).filter(function (value) {
return value !== null;
});

return attribute + ":(" + values + ")";
}).filter(function(value) {
return value !== null;
});
if (filterString.length > 0) {
queryString += " AND (" + filterString.join(") AND (") + ")";
if (filterString.length > 0) {
var queryString = "(" + filterString.join(") AND (") + ")";
return {query_string: {query: queryString}}; // eslint-disable-line camelcase
}
}

return queryString;
return {match_all: {}}; // eslint-disable-line camelcase
};

ElasticsearchStore.prototype._applySort = function(request) {
Expand Down Expand Up @@ -128,13 +134,26 @@ ElasticsearchStore.prototype._generateMappingFor = function(resourceConfig) {
};


ElasticsearchStore.prototype._getSource = function(ressource) {
var source = ressource._source;
if(!source.id) {
source.id = ressource._id;
}
if(!source.type) {
source.type = ressource._type;
}

return source;
};


/**
initialise gets invoked once for each resource that uses this hander.
*/
ElasticsearchStore.prototype.initialise = function(resourceConfig) {
var self = this;
var clientConfig = {
host: "http://localhost:9200"
host: self.config.host
};
var client = new elasticsearch.Client(JSON.parse(JSON.stringify(clientConfig)));
if (!client) {
Expand All @@ -148,14 +167,14 @@ ElasticsearchStore.prototype.initialise = function(resourceConfig) {

ElasticsearchStore.prototype.populate = function(callback) {
var self = this;
self._db.indices.delete({ index: "jsonapi" }, function(err) {
self._db.indices.delete({ index: self.config.index }, function(err) {
if (err) console.log("Error dropping index?", err.message);

self._db.indices.create({ index: "jsonapi" }, function(err1) {
self._db.indices.create({ index: self.config.index }, function(err1) {
if (err1) console.log("Error creating index?", err1);

var mappingRequest = {
index: "jsonapi",
index: self.config.index,
type: self.resourceConfig.resource,
body: self._generateMappingFor(self.resourceConfig)
};
Expand All @@ -180,7 +199,7 @@ ElasticsearchStore.prototype.populate = function(callback) {
ElasticsearchStore.prototype.create = function(request, newResource, callback) {
var self = this;
self._db.index({
index: "jsonapi",
index: self.config.index,
type: newResource.type,
id: newResource.id,
body: newResource,
Expand All @@ -204,7 +223,7 @@ ElasticsearchStore.prototype.create = function(request, newResource, callback) {
ElasticsearchStore.prototype.find = function(request, callback) {
var self = this;
self._db.get({
index: "jsonapi",
index: self.config.index,
type: request.params.type,
id: request.params.id
}, function(err, theResource) {
Expand All @@ -218,7 +237,7 @@ ElasticsearchStore.prototype.find = function(request, callback) {
}

debug("find", JSON.stringify(theResource._source));
return callback(null, theResource._source);
return callback(null, self._getSource(theResource));
});
};

Expand All @@ -228,8 +247,11 @@ ElasticsearchStore.prototype.find = function(request, callback) {
ElasticsearchStore.prototype.search = function(request, callback) {
var self = this;
var params = _.assign({
index: "jsonapi",
q: self._buildQuery(request)
index: self.config.index,
type: request.params.type,
body: {
query: self._buildQuery(request)
}
}, self._applyPagination(request), self._applySort(request));

debug("search", JSON.stringify(params));
Expand All @@ -251,7 +273,7 @@ ElasticsearchStore.prototype.search = function(request, callback) {
results = results.resultSet[0].hits.hits;
if(!(results instanceof Array)) results = [results];
results = results.map(function(result) {
return result._source;
return self._getSource(result);
});

debug("search", JSON.stringify(results));
Expand Down Expand Up @@ -296,7 +318,7 @@ ElasticsearchStore.prototype.update = function(request, partialResource, callbac
ElasticsearchStore.prototype.delete = function(request, callback) {
var self = this;
self._db.delete({
index: "jsonapi",
index: self.config.index,
type: request.params.type,
id: request.params.id
}, function(err, response) {
Expand Down