MongoDb中的TextSearch引擎

时间:2014-05-29 09:59:23

标签: c# mongodb

我尝试使用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" } }

由于词干和停止词的阐述而给我错误的结果(我认为):

enter image description here

2 个答案:

答案 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" } }

和词干会帮助你,而不是打扰