MongoDB 文本搜索 - 匹配字符串中的确切标记
MongoDB text search - Match exact tokens in a string
我陷入了这样一种情况,我需要通过在字符串中匹配 exact 标记来在 MongoDB 中执行 $text $search。我想我可以通过创建一个没有默认语言的文本索引来解决这个问题,并通过用 \"token\"
包装每个标记来执行查询,如 documentation 中所写。所以我以这种方式创建了我的索引:
db.collection.createIndex({"denom": "text"}, {"default_language": "none"})
我必须执行的查询是
db.collection.find( {"$text": {"$search": "\"consorzio\" \"la\""}}, {"denom": 1} )
我期望的结果是所有文档都恰好包含标记 "consorzio"
和 "la"
,但此查询匹配其标记包含字符串 [=53= 的文档] 和 "consorzio" 在每个令牌中
例如,上面的查询 returns 我期望以下 denom 的值:
- CONSORZIO LA* CASCINA 好的
- LA RADA CONSORZIO 好的
- GESCO CONSORZIO AGRICOLA 错误
有人可以解决这个问题吗?我希望问题很清楚。
非常感谢您。
Mongodb 已报告此 issue 的错误。精确加工不起作用。
你可以看看机器评分:
db.docs.find({$text: {$search: "\"consorzio\" \"la\""}},
{score: { $meta: "textScore" }, "_id": 0})
{ "t" : "CONSORZIO LA* CASCINA OK", "score" : 1.25 }
{ "t" : "LA RADA CONSORZIO OK", "score" : 1.25 }
{ "t" : "GESCO CONSORZIO AGRICOLA WRONG", "score" : 0.625 }
一个解决方案应该是考虑最高分...
Fernando 你实际上错了它匹配 GESCO CONSORZIO AGRICOLA WRONG
但它只匹配你搜索的一个词(标记)是 consorzio
而不是 la
.
In a text search textScore
will be greater then 1 when it will
match all the tokens of the query.
例如这是一个商店集合
db.stores.insert(
[
{ _id: 1, name: "Java Hut", description: "Coffee and cakes" },
{ _id: 2, name: "Burger Buns", description: "Gourmet hamburgers" },
{ _id: 3, name: "Coffee Java Shop", description: "Just coffee" },
{ _id: 4, name: "Clothes Clothes Clothes", description: "Discount clothing" },
{ _id: 5, name: "Java Shopping", description: "Indonesian goods" },
{ _id: 6, name: "Java Hut", description: "Coffee and cakes" }
]
)
索引
db.stores.createIndex( { name: "text" } )
现在如果我查询
db.stores.find({
$text: {
$search: "Java Shop"
}
}, {
score: {
$meta: "textScore"
}
}).sort({
score: {
$meta: "textScore"
},
_id: -1
})
它将匹配标记,结果是
/* 1 */
{
"_id" : 6.0,
"name" : "Java Shopping",
"description" : "Indonesian goods",
"score" : 1.5
}
/* 2 */
{
"_id" : 5.0,
"name" : "Java Shopping",
"description" : "Indonesian goods",
"score" : 1.5
}
/* 3 */
{
"_id" : 3.0,
"name" : "Java Coffee Shop",
"description" : "Just coffee",
"score" : 1.33333333333333
}
/* 4 */
{
"_id" : 1.0,
"name" : "Java Hut",
"description" : "Coffee and cakes",
"score" : 0.75
}
在这里您可以看到前三个文档匹配所有标记,这就是为什么 score
大于 1 而最后一个文档 score
小于 1 的原因,因为它只匹配一个标记。
现在您还可以获得与得分大于 1 的所有标记匹配的最佳文档。为此,我们需要使用 MongoDB 聚合。
db.stores.aggregate([
{
"$match": {
"$text": {
"$search": "Java Shop"
}
}
},
{
"$addFields": {
"score": {
"$meta": "textScore"
}
}
},
{
"$match": {
"score": { "$gt": 1.0 }
}
},
{
"$sort": {
"score": -1, _id: -1
}
},
{
"$limit": 1
}
])
& 这是结果
/* 1 */
{
"_id" : 6.0,
"name" : "Java Shopping",
"description" : "Indonesian goods",
"score" : 1.5
}
我陷入了这样一种情况,我需要通过在字符串中匹配 exact 标记来在 MongoDB 中执行 $text $search。我想我可以通过创建一个没有默认语言的文本索引来解决这个问题,并通过用 \"token\"
包装每个标记来执行查询,如 documentation 中所写。所以我以这种方式创建了我的索引:
db.collection.createIndex({"denom": "text"}, {"default_language": "none"})
我必须执行的查询是
db.collection.find( {"$text": {"$search": "\"consorzio\" \"la\""}}, {"denom": 1} )
我期望的结果是所有文档都恰好包含标记 "consorzio"
和 "la"
,但此查询匹配其标记包含字符串 [=53= 的文档] 和 "consorzio" 在每个令牌中
例如,上面的查询 returns 我期望以下 denom 的值:
- CONSORZIO LA* CASCINA 好的
- LA RADA CONSORZIO 好的
- GESCO CONSORZIO AGRICOLA 错误
有人可以解决这个问题吗?我希望问题很清楚。
非常感谢您。
Mongodb 已报告此 issue 的错误。精确加工不起作用。
你可以看看机器评分:
db.docs.find({$text: {$search: "\"consorzio\" \"la\""}},
{score: { $meta: "textScore" }, "_id": 0})
{ "t" : "CONSORZIO LA* CASCINA OK", "score" : 1.25 }
{ "t" : "LA RADA CONSORZIO OK", "score" : 1.25 }
{ "t" : "GESCO CONSORZIO AGRICOLA WRONG", "score" : 0.625 }
一个解决方案应该是考虑最高分...
Fernando 你实际上错了它匹配 GESCO CONSORZIO AGRICOLA WRONG
但它只匹配你搜索的一个词(标记)是 consorzio
而不是 la
.
In a text search
textScore
will be greater then 1 when it will match all the tokens of the query.
例如这是一个商店集合
db.stores.insert(
[
{ _id: 1, name: "Java Hut", description: "Coffee and cakes" },
{ _id: 2, name: "Burger Buns", description: "Gourmet hamburgers" },
{ _id: 3, name: "Coffee Java Shop", description: "Just coffee" },
{ _id: 4, name: "Clothes Clothes Clothes", description: "Discount clothing" },
{ _id: 5, name: "Java Shopping", description: "Indonesian goods" },
{ _id: 6, name: "Java Hut", description: "Coffee and cakes" }
]
)
索引
db.stores.createIndex( { name: "text" } )
现在如果我查询
db.stores.find({
$text: {
$search: "Java Shop"
}
}, {
score: {
$meta: "textScore"
}
}).sort({
score: {
$meta: "textScore"
},
_id: -1
})
它将匹配标记,结果是
/* 1 */
{
"_id" : 6.0,
"name" : "Java Shopping",
"description" : "Indonesian goods",
"score" : 1.5
}
/* 2 */
{
"_id" : 5.0,
"name" : "Java Shopping",
"description" : "Indonesian goods",
"score" : 1.5
}
/* 3 */
{
"_id" : 3.0,
"name" : "Java Coffee Shop",
"description" : "Just coffee",
"score" : 1.33333333333333
}
/* 4 */
{
"_id" : 1.0,
"name" : "Java Hut",
"description" : "Coffee and cakes",
"score" : 0.75
}
在这里您可以看到前三个文档匹配所有标记,这就是为什么 score
大于 1 而最后一个文档 score
小于 1 的原因,因为它只匹配一个标记。
现在您还可以获得与得分大于 1 的所有标记匹配的最佳文档。为此,我们需要使用 MongoDB 聚合。
db.stores.aggregate([
{
"$match": {
"$text": {
"$search": "Java Shop"
}
}
},
{
"$addFields": {
"score": {
"$meta": "textScore"
}
}
},
{
"$match": {
"score": { "$gt": 1.0 }
}
},
{
"$sort": {
"score": -1, _id: -1
}
},
{
"$limit": 1
}
])
& 这是结果
/* 1 */
{
"_id" : 6.0,
"name" : "Java Shopping",
"description" : "Indonesian goods",
"score" : 1.5
}