mongodb 猫鼬中的权重全文搜索
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24714166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Full text search with weight in mongoose
提问by Foad Nosrati Habibi
As I find out, since version 3.8.9, mongoose support full text search. But I can't find a good documentation for it!
I want to do something like:
据我所知,从 3.8.9 版开始,猫鼬支持全文搜索。但是我找不到好的文档!
我想做类似的事情:
db.collection.ensureIndex(
// Fields to index
{
animal: "text",
color: "text",
pattern: "text",
size: "text"
},
// Options
{
name: "best_match_index",
// Adjust field weights (default is 1)
weights: {
animal: 5, // Most relevant search field
size: 4 // Also relevant
}
}
)
Can I do it with pure mongoose? Or I have to use some plugin like mongoose-text-search? How about without weight?
And how should I do it?
我可以用纯猫鼬做吗?或者我必须使用一些插件,比如mongoose-text-search?没有重量怎么办?
我该怎么做?
回答by eagor
Yes, you can use full text search in Mongoose >= 3.8.9. Firstly, a collection can have at most one text index (see docs). So, to define text index for several fields, you need compound index:
是的,您可以在 Mongoose >= 3.8.9 中使用全文搜索。首先,一个集合最多可以有一个文本索引(参见docs)。因此,要为多个字段定义文本索引,您需要复合索引:
schema.index({ animal: 'text', color: 'text', pattern: 'text', size: 'text' });
Now you can use $textquery operatorlike this:
现在您可以像这样使用$text查询运算符:
Model
.find(
{ $text : { $search : "text to look for" } },
{ score : { $meta: "textScore" } }
)
.sort({ score : { $meta : 'textScore' } })
.exec(function(err, results) {
// callback
});
This will also sort results by relevance score.
这也将按相关性分数对结果进行排序。
As for weights, you can try to pass weights options object to index()
method (where you define compound index) (working at least with v4.0.1 of mongoose):
至于weights,您可以尝试将 weights 选项对象传递给index()
方法(在其中定义复合索引)(至少与 mongoose 的 v4.0.1 一起使用):
schema.index({ animal: 'text', color: 'text', pattern: 'text', size: 'text' }, {name: 'My text index', weights: {animal: 10, color: 4, pattern: 2, size: 1}});
回答by wdberkeley
As of MongoDB 2.6, a collection can have at most one text index (documented here). Therefore, you will not be able to do what you want with the current version of MongoDB. Really, for complicated text searching problems with requirements of different weights depending on the location of the match, you should consider a full-blown text searching solution like Solr or ElasticSearch.
从 MongoDB 2.6 开始,一个集合最多可以有一个文本索引(在此处记录)。因此,您将无法使用当前版本的 MongoDB 执行您想要的操作。确实,对于需要根据匹配位置不同权重的复杂文本搜索问题,您应该考虑使用成熟的文本搜索解决方案,如 Solr 或 ElasticSearch。
As a workaround in MongoDB, you could tokenize the fields manually, store them as keyword arrays, and index them:
作为 MongoDB 中的一种解决方法,您可以手动标记字段,将它们存储为关键字数组,并索引它们:
animal: ["The", "quick", "brown", "fox", "jump", ..., "dog"]
then a query like
然后像这样的查询
db.test.find({animal: {$in: ["brown", "shoes"]})
db.test.find({animal: {$in: ["brown", "shoes"]})
mimics text search. There are a few limitations of this approach like the manual work required to set it up, the fact that there will be no stemming to, e.g., match "dreaming" with "dream", the fact that stopwords will not be removed like in a normal text index, and the absence of any weighting mechanism.
模仿文本搜索。这种方法有一些限制,比如设置它所需的手动工作,没有词干的事实,例如将“梦想”与“梦想”匹配,不会像在正常的文本索引,并且没有任何加权机制。
回答by Gordon Deudney
I found the following article that led me to the http://code.tutsplus.com/tutorials/full-text-search-in-mongodb--cms-24835I dropped the index created in the top answer using the following
我发现以下文章使我进入了http://code.tutsplus.com/tutorials/full-text-search-in-mongodb--cms-24835我使用以下内容删除了在最佳答案中创建的索引
db.tablename.dropIndex({"indexname_text"})
I got the list of indexes with this command
我用这个命令得到了索引列表
db.tablename.getIndexes()
I then used the following to create the indexes
然后我使用以下内容来创建索引
db.tablename.createIndex({"$**":"text"})
the following commands worked in Mongoose
以下命令适用于猫鼬
model.find(
{$text: {$search: "text you are searching for"}},
{score: {$meta: "textScore"}})
.sort({score:{$meta:"textScore"}}
)
.exec(function(err, results) {
`enter code here`if(!err){
console.log('results ' + results);
}
else
{
console.log(err);
}
});
回答by dam1
var searchQuery=new RegExp('dam', 'i');
var query = { firstName : searchQuery };
Model.find(query ...