I am strugling for two or three days locking for a very simple task: get the result of search and fill in a model. I have done this task many time with MongoDb but I am complety stuck with ElasticSearch and I am sure it must exist some easy way to do but I can't find a north. I have read a lot around but I am really stuck.
I can see the result of search. If someone at least tell me how to take away _index, _type, _id and _score and return just the _source as an array it may be useful.
I understand, as far as I can see, that ElasticSearch was designed with speed in mind so _score is part of the reason to use ElasticSearch. In my case, I must use only ElasticSearch in our server because they allow ElasticSearch in such server and ElasticSearch is already used for LogStash and Kibana. I am very happy with such challenge and I have been learning a lot about ElasticSearch but I do need some north about "serialize/desearile" the _source content in order move forward.
I put my entire code bellow. I guess that there may exist a clue using Schema and mongoosastic but I am really without ideas what to try.
You can see I created a model with schema and I added the plugin mongoosastic. I guess it might exist some way to use such model with ElasticSearch similar as we easily do with MOngoDb but I don't know how.
Server.js
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var esController = require('./controllers/mycontroller');
mongoose.connect('mongodb://localhost:27017/greencard');
var app = express();
var router = express.Router();
router.route('/myexposedmethod')
.get(esController.myexposedmethod);
app.use('/api', router);
app.listen(3000);
package.json
{
"name": "greencard-dmz-es-oracle",
"main": "server.js",
"dependencies": {
"elasticsearch": "^12.1.3",
"express": "^4.1.1",
"express-session": "^1.6.1",
"mongoosastic": "^4.2.4",
"mongoose": "^3.8.8",
"reqclient": "^2.1.0"
}
}
mycontroller.js
var elasticsearch = require('elasticsearch');
var Promise = require('bluebird');
var Mymodel = require('../models/mymodel');
var query = {
"bool": {
"must": {
"term": { "my_prop1": "my" }
}
}
}
exports.myexposedmethod = function (req, res) {
var client = new elasticsearch.Client({
host: 'localhost:9200',
//log: 'trace'
});
function closeConnection() {
client.close();
}
function createIndex() {
return client.indices.create({
index: "myindex",
body: {
"mappings": {
"my_type": {
"properties": {
"my_prop1": { "type": "string" }
}
}
}
}
}
);
}
function addToIndex() {
return client.index({
index: 'myindex',
type: 'my_type',
body: {
my_prop1: 'my second string to be inserted'
},
refresh: true
});
}
function search() {
return client.search({
index: 'myindex',
type: 'my_type',
body: {
query: {
match: {
my_prop1: {
query: 'my'
}
}
}
}
}).then(function (resp) {
var hits = resp.hits.hits;
console.log(hits.length);
hits.forEach(function (hit) {
console.log("_source: ", hit._source);
})
//I know it is not going to work but may express what I am locking for
//var mymodel_result = JSON.stringify({
// mymodel: hits._source
//});
//the return to http://localhost:3000/api/myexposedmethod is
/*[
{
"_index": "myindex",
"_type": "my_type",
"_id": "AVpmQ4GbDU4zGDgLLeeR",
"_score": 0.16948202,
"_source": {
"my_prop1": "my first string to be inserted"
}
},
{
"_index": "myindex",
"_type": "my_type",
"_id": "AVpmXus8DU4zGDgLLeeU",
"_score": 0.16948202,
"_source": {
"my_prop1": "my second string to be inserted"
}
}
]*/
//but I want something like
//[{"my_prop1": "my first string to be inserted"},{"my_prop1": "my second string to be inserted"}]
//or
//[{"mymodel": "my first string to be inserted"},{"mymodel": "my second string to be inserted"}]
return res.json(hits);
}, function (err) {
console.trace(err.message);
});
}
Promise.resolve()
//.then(createIndex)
//.then(addToIndex)
.then(search)
.then(closeConnection)
;
};
mymodel.js inspirid in how I use to work with MongoDb plus mongooastic
var mongoose = require('mongoose'),
mongoosastic = require('mongoosastic'),
Schema = mongoose.Schema
var myschema = new Schema(
{ my_prop1: String }
)
myschema.plugin(mongoosastic)
You just have to map the resp.hits.hits
array to an array formatted to your liking.
var newArray = resp.hits.hits.map(function(hit) {
return hit._source;
});
newArray
will contain all the _source field from the resp.hits.hits array, so it will look like this:
[{"my_prop1": "my first string to be inserted"},{"my_prop1": "my second string to be inserted"}]