0

Je me bloque pendant deux ou trois jours pour une tâche très simple: obtenir le résultat d'une recherche et remplir un modèle. J'ai fait cette tâche plusieurs fois avec MongoDb mais je suis complètement coincé avec ElasticSearch et je suis sûr qu'il doit exister un moyen facile de le faire mais je ne peux pas trouver un nord. J'ai beaucoup lu mais je suis vraiment coincé.Comment créer une chaîne json avec une liste de hits._source en utilisant NodeJs et ElastiSearch

Je peux voir le résultat de la recherche. Si quelqu'un au moins me dit comment enlever _index, _type, _id et _score et retourner juste le _source comme tableau il peut être utile. Je comprends, autant que je peux voir, que ElasticSearch a été conçu avec la vitesse à l'esprit donc _score fait partie de la raison d'utiliser ElasticSearch. Dans mon cas, je dois utiliser uniquement ElasticSearch dans notre serveur car ils permettent ElasticSearch dans un tel serveur et ElasticSearch est déjà utilisé pour LogStash et Kibana. Je suis très heureux avec un tel défi et j'ai beaucoup appris sur ElasticSearch, mais j'ai besoin d'un peu de nord sur "sérialiser/désirer" le contenu de la source afin d'aller de l'avant.

Je mets tout mon code ci-dessous. Je suppose qu'il peut exister une idée en utilisant Schema et mongoosastic mais je suis vraiment sans idées quoi essayer.

Vous pouvez voir que j'ai créé un modèle avec un schéma et j'ai ajouté le plugin mongoosastic. Je suppose qu'il pourrait exister un moyen d'utiliser un tel modèle avec ElasticSearch similaire à celui que nous faisons facilement avec MOngoDb mais je ne sais pas comment.

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 dans la façon dont j'utiliser pour travailler avec MongoDB, plus mongooastic

var mongoose = require('mongoose'), 
    mongoosastic = require('mongoosastic'), 
    Schema = mongoose.Schema 

var myschema = new Schema(
    { my_prop1: String } 
) 

myschema.plugin(mongoosastic) 
+1

ElasticSearch retournera les résultats JSON, de sorte que vous n'avez pas besoin sérialiser/désérialiser. Utilisez-le comme un json normal. par exemple. ** res ["_ source"] **, qui vous donnera un objet ou un tableau en fonction de votre recherche. – Hosar

Répondre

0

Vous venez de mapper le tableau resp.hits.hits à un tableau formaté à votre goût.

var newArray = resp.hits.hits.map(function(hit) { 
return hit._source; 
}); 

newArray contiendra tout le champ source_ du tableau resp.hits.hits, il ressemblera à ceci:

[{"my_prop1": "my first string to be inserted"},{"my_prop1": "my second string to be inserted"}]