在猫鼬中使用权重进行全文搜索
Posted
技术标签:
【中文标题】在猫鼬中使用权重进行全文搜索【英文标题】:Full text search with weight in mongoose 【发布时间】:2014-09-03 01:10:54 【问题描述】:据我所知,从 3.8.9 版本开始,mongoose 支持全文搜索。但是我找不到它的好文档! 我想做类似的事情:
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
)
我可以用纯猫鼬做吗?或者我必须使用像mongoose-text-search 这样的插件?没有重量怎么办? 我该怎么做?
【问题讨论】:
您是否尝试过在架构上调用index
来添加文本索引?
我在架构中将其作为索引:'text',但我想对多个字段进行索引,如上例所示。
不要在架构定义中声明它,调用架构的index
方法。 mongoosejs.com/docs/api.html#schema_Schema-index
你的意思是'schema.index( animal: "text", color: "text", pattern: "text", size: "text" )' ?体重呢?它是创建单个索引还是 4 个索引?
【参考方案1】:
是的,您可以在 Mongoose >= 3.8.9 中使用全文搜索。首先,一个集合最多可以有一个文本索引(参见docs)。因此,要为several fields 定义文本索引,您需要复合索引:
schema.index( animal: 'text', color: 'text', pattern: 'text', size: 'text' );
现在你可以像这样使用$text query operator:
Model
.find(
$text : $search : "text to look for" ,
score : $meta: "textScore"
)
.sort( score : $meta : 'textScore' )
.exec(function(err, results)
// callback
);
这还将按相关性分数对结果进行排序。
至于weights,您可以尝试将权重选项对象传递给index()
方法(您可以在其中定义复合索引)(至少使用v4.0.1 的mongoose):
schema.index( animal: 'text', color: 'text', pattern: 'text', size: 'text' , name: 'My text index', weights: animal: 10, color: 4, pattern: 2, size: 1);
【讨论】:
返回错误:$text 查询需要一个文本索引 要为多个字段定义文本索引,您需要复合索引。确保您正确定义复合索引。 此过程是否记录在某处?我正在尝试将文本索引与猫鼬一起使用,但它不起作用。我创建了一个复合索引,我使用了像您的示例一样的 $text 运算符,但结果始终是一个空文档。 见$text doc 和text search tutorials。你的猫鼬版本是什么? (全文搜索适用于版本 >= 3.8.9) @Mallen 你找到解决方案了吗?【参考方案2】:从 MongoDB 2.6 开始,一个集合最多可以有一个文本索引(记录在 here)。因此,您将无法使用当前版本的 MongoDB 做您想做的事情。确实,对于根据匹配位置要求不同权重的复杂文本搜索问题,您应该考虑使用完整的文本搜索解决方案,如 Solr 或 ElasticSearch。
作为 MongoDB 中的一种解决方法,您可以手动标记字段,将它们存储为关键字数组,并为它们编制索引:
animal: ["The", "quick", "brown", "fox", "jump", ..., "dog"]
然后是这样的查询
db.test.find(animal: $in: ["brown", "shoes"])
模仿文本搜索。这种方法有一些限制,例如设置它所需的手动工作,没有词干匹配,例如,将“梦想”与“梦想”匹配,停用词不会像在正常的文本索引,并且没有任何加权机制。
【讨论】:
事实上,我只有一个包含多个字段的文本索引。打击代码是 .getIndexes() 的一部分。我用mongoose-text-search 做的,我正在寻找它的纯猫鼬版本。 ` “v”:1,“key”:“_fts”:“text”,“_ftsx”:1,“ns”:“public-diary-dev.diaries”,“name”:“完整搜索-index”,“背景”:真,“权重”:“标签”:1,“文本”:1,“标题”:1,“默认语言”:“英语”,“语言覆盖”:“语言”, “文本索引版本”:1 `【参考方案3】:我发现以下文章将我带到了http://code.tutsplus.com/tutorials/full-text-search-in-mongodb--cms-24835 我使用以下方法删除了在最佳答案中创建的索引
db.tablename.dropIndex("indexname_text")
我用这个命令得到了索引列表
db.tablename.getIndexes()
然后我使用以下内容创建索引
db.tablename.createIndex("$**":"text")
以下命令在 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);
);
【讨论】:
【参考方案4】: var searchQuery=new RegExp('dam', 'i');
var query = firstName : searchQuery ;
Model.find(query ...
【讨论】:
这个答案就是炸弹!我浪费了最后两个小时试图将文本索引添加到我的架构中,而我只需要这个简单的答案。嘘! 是的,但是你不能创建人性化的查询避免使用正则表达式。 小心这个,因为它可能会意外导致regex denial of service vulnerability 完全同意BrotherDonkey ...请在考虑安全的情况下发布答案!以上是关于在猫鼬中使用权重进行全文搜索的主要内容,如果未能解决你的问题,请参考以下文章