我尝试使用c#Driver for MongoDb在我的应用程序中创建搜索功能。
当用户搜索我想要显示的单词列表时,首先是完全匹配(如果存在),然后是最有趣的帖子。
我是这样的文字索引:
collection.CreateIndex(IndexKeys<Post>.Text(p => p.BodyPlainText));
我是这样开始的:
var textSearchQueryExact = Query.Matches("BodyPlainText", searchString);
var textSearchQueryFullText = Query.Text(searchString);
var textSearchQuery = Query.Or(textSearchQueryFullText, textSearchQueryExact);
这将生成以下查询:
{ "$or" : [ { "$text" : { "$search" : "My example text" } }, { "BodyPlainText" : /My example text/ }] }
但它不起作用!零结果,在MongoVUE中,我没有接受任何解释。如果我删除了两个查询过滤器中的一个,则可以同时使用两个查询过滤器。
我也在Mongo文档中找到了这个限制:
"To use a $text query in an $or expression, all clauses in the $or array must be indexed."
但是这个属性是相同的,它被编入索引。
我想念的是什么?
这是实现我想要的结果的正确方法吗?
更新
仅使用具有以下语法的textSearch查询:
{ "$text" : { "$search" : "il ricorrente lamentava che mentre" } }
由于词干和停止词的阐述而给我错误的结果(我认为):
答案 0 :(得分:2)
嗯,你可以这样做,因为产生的错误信息说你应该处理这个。这实际上是“索引交集”在MongoDB 2.6及更高版本中如何工作的一部分。之前有$or
个受影响的查询“有点”,但现在还有更多的“幕后”。所以基本上添加像错误一样的索引要求你:
考虑数据:
db.example.insert({ "text": "This is what I want" })
然后添加索引:
db.example.ensureIndex({ "text": "text" })
db.example.ensureIndex({ "text": 1 })
然后查询按预期工作:
db.example.find(
{
"$or": [
{ "$text": { "$search": "This is what I want" } },
{ "text": /This is what I want/ }
]
},
{ "score": { "$meta": "textScore" } }
).pretty()
注意到即使.sort()
被省略,我确实在其中添加了$meta
。但几乎我从评论中得出的结论是,这实际上是相同的:
db.example.find(
{
"$or": [
{ "$text": { "$search": "This is what I want" } }
]
},
{ "score": { "$meta": "textScore" } }
).pretty()
因此,虽然在第一个示例中努力“相交”,但完全匹配的文档分数将保持不变:
{
"_id" : ObjectId("53870b75015cb64be54d7ecf"),
"text" : "This is what I want",
"score" : 1
}
如您所提及的更多“阻塞”示例,请考虑以下事项:
db.example.insert({ "text": "these colors are mine" })
db.example.insert({ "text": "This color are mine" })
以及两种查询形式:
db.example.find(
{
"$or": [
{ "$text": { "$search": "This color are mine" } },
{ "text": /This color are mine/ }
]
},
{ "score": { "$meta": "textScore" }}
).pretty()
db.example.find(
{
"$or": [
{ "$text": { "$search": "This color are mine" } }
]
},
{ "score": { "$meta": "textScore" }}
).pretty()
在所有情况下都使用$or
,但复制和粘贴速度很快。但报告再次返回相同的值:
{
"_id" : ObjectId("53870f5a015cb64be54d7ed0"),
"text" : "these colors are mine",
"score" : 1.5
},
{
"_id" : ObjectId("5387114b015cb64be54d7ed1"),
"text" : "This color are mine",
"score" : 1.5
}
因此,在使用该表单进行查询时,排名几乎是如何排序的。
答案 1 :(得分:1)
尝试在索引中设置默认语言
db.CollectionName.ensureIndex(
{ BodyPlainText: "text" },
{ default_language: "it" }
)
并在查询中
{ $text: { $search: "il ricorrente lamentava che mentre", $language: "it" } }
和词干会帮助你,而不是打扰