Use mongoosastic for an autocomplete Use mongoosastic for an autocomplete elasticsearch elasticsearch

Use mongoosastic for an autocomplete


Here is a complete solution for a basic autocomplete:

  1. Add the necessary parameters to your schema:

    var TagSchema = new Schema({    name: {        type: String,        unique: true,        required: true,        es_type: 'completion',        es_index_analyzer: 'simple',        es_search_analyzer: 'simple',        es_payloads: true    }});
  2. Add the plugin to your schema and create the model:

    TagSchema.plugin(mongoosastic);var Tag = mongoose.model('Tag', TagSchema);
  3. Use the create mapping method to register the mapping with ES. If you don't do this step your index will get registered with defaults, when the first document is created and indexed:

    Tag.createMapping(function(err, mapping) {    if (err) {        console.log('error creating mapping (you can safely ignore this)');        console.log(err);    } else {        console.log('mapping created!');        console.log(mapping);    }});
  4. *Optional - Index existing documents in your database:

    var stream = Tag.synchronize(),    count = 0;stream.on('data', function(err, doc) {    count++;});stream.on('close', function() {    console.log('indexed ' + count + ' documents!');});stream.on('error', function(err) {    console.log(err);});
  5. Search with an empty query body and supply two options - 1) Use the ES suggest query which uses the "es_completion" field we created in our schema; 2) size = 0 so that no tags are returned by the empty body query.

    Tag.search(null, {    suggest: {        "tag-suggest": {            "text": "aTermToAutocomplete",            "completion": {                "field": "name"            }        }    },    "size" : 0},function(err, results) {    if (err) {        return console.log(JSON.stringify(err, null, 4));    }    return console.log(JSON.stringify(results, null, 4));});


I have found a way. With the latest update to mongoosastic library you could just do something like this:

GET _search{    "query": {       "match_all": {}    },    "suggest": {        "story-suggest": {            "text": "bow",            "completion": {                "field": "title"            }        }    }}

This is because the new mongoosastic version supports suggesters. Just be aware of what you are doing, specially in the query part, as a "match_all" would match all the documents and give you an unnecessarily big response; but whatever you place in the "text" part of your suggester would return you the words to autocomplete.

Also be aware that in order for this to work, you need to use the createMapping method in your model definition, like this:

var StorySchema = new Schema({    title:{        type: String, es_type:'completion', es_index_analyzer: 'simple', es_search_analyzer: 'simple', es_payloads: true    },    description: {         type: String    }});StorySchema.plugin(mongoosastic);var Story = mongoose.model('Story', StorySchema);Story.createMapping({}, function(err, mapping){    // ...});