使用mongoosastic来自动完成
我正在尝试使用mongoosastic和Elastic Search创build一个自动完成,到目前为止,我已经能够使用感觉来创build自动完成,但是我无法将其移植到mongoosastic中。
我遵循ElasticSearch文档中的这个教程,我能够通过一个如下所示的映射来实现我想要的“sense”:
PUT storys/story/_mapping { "story" : { "properties": { "description": { "type": "string" }, "title": { "type" : "completion", "index_analyzer": "simple", "search_analyzer": "simple" } } } }
和这样的查询:
GET storys/_suggest { "story-suggest": { "text": "bow", "completion": { "field": "title" } } }
不过,我无法将其移植到mongoosastic中。 我尝试了以下方法:
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);
当从服务器控制器查询时:
Story.search({ query: { "match": { title : req.query.q } }, suggest: { "my-title-suggestions-1" :{ text: req.query.q, completion: { field: 'title' } } } });
我明白,当我使用“sense”时,我正在使用_suggest端点,这就是“故事build议”查询起作用的原因。 但是,在使用mongoosastic时,我仅限于使用.search({})来查询_search的行为。 但是,我似乎无法find一种方法来实现我正在寻求自动完成的_suggest行为,并且当我尝试使用提示执行查询时,我一直在ElasticSearch中发生parsing错误。
有没有一种方法可以完成我想要做的与mongoosastic或弹性search?
我已经尝试使用“感”做这个,但即使我得到了“自动完成”的build议,我也得到了一堆SearchParseExceptions:
GET _search { "query": { "match": { title : "bow" } }, "suggest": { "story-suggest": { "text": "bow", "completion": { "field": "title" } } } }
以下是基本自动完成的完整解决scheme:
-
将必要的参数添加到您的模式中:
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 } });
-
将插件添加到您的模式并创build模型:
TagSchema.plugin(mongoosastic); var Tag = mongoose.model('Tag', TagSchema);
-
使用create mapping方法向ES注册映射。 如果你不这样做,那么当第一个文档被创build并build立索引时,你的索引将被默认注册:
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); } });
-
*可选 – 索引数据库中的现有文档:
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); });
-
search一个空的查询体,并提供两个选项 – 1)使用ES
suggest
查询,它使用我们在模式中创build的“es_completion”字段; 2)size = 0
这样没有标签由空的正文查询返回。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)); });
我find了一个方法。 随着mongoosastic库的最新更新,你可以做这样的事情:
GET _search { "query": { "match_all": {} }, "suggest": { "story-suggest": { "text": "bow", "completion": { "field": "title" } } } }
这是因为新的mongoosastic版本支持build议者。 只要知道你在做什么,特别是在查询部分,因为“match_all”会匹配所有的文件,并给你一个不必要的大回应; 但是无论您在build议者的“文本”部分放置什么内容,都会将字词返回给自动填充。
另外请注意,为了使其工作,您需要在模型定义中使用createMapping方法,如下所示:
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){ // ... });