【发布时间】:2020-04-21 18:02:04
【问题描述】:
如何使用$text query operator 查找不包含禁用词列表的文档?文件不需要包含任何具体内容;只是没有这些词。
这是一个非常常见的用例,例如用于过滤脏话,但the MongoDB documentation 声明,没有任何解释或解决方法,即
当传递一个只包含否定词的搜索字符串时,文本搜索将不匹配任何文档。
【问题讨论】:
如何使用$text query operator 查找不包含禁用词列表的文档?文件不需要包含任何具体内容;只是没有这些词。
这是一个非常常见的用例,例如用于过滤脏话,但the MongoDB documentation 声明,没有任何解释或解决方法,即
当传递一个只包含否定词的搜索字符串时,文本搜索将不匹配任何文档。
【问题讨论】:
$text 运算符需要至少一个包含的单词才能匹配。然后,您可以在包含后尽可能多地使用禁用词,如下所示:
db.articles.find({
$text: {
$search: "coffee -cream -shop"
}
})
我猜这是 mongodb 文本搜索引擎的限制。
所以,另一种方法是这样做:
db.articles.find(
{
subject: {
$not: {
$in: [/cream/i, /shop/i]
}
}
}
)
【讨论】:
没有MongoDB不支持这个功能,我猜所有的解决方案都会被破解。
这是我的:
我会为我的集合创建一个具有相同静态值的虚拟字段,例如"dummy":"x"。并将此字段添加到文本索引。最后将这个虚拟值 x 添加到查询中以克服以下限制:
当传递一个只包含否定词的搜索字符串时,文本 搜索将不匹配任何文档
db.articles.insert(
[
{ _id: 1, subject: "coffee", dummy: "x" },
{ _id: 2, subject: "Coffee Shopping", dummy: "x" },
{ _id: 3, subject: "Baking a cake", dummy: "x" },
{ _id: 4, subject: "baking", dummy: "x" },
{ _id: 5, subject: "Cafe Con Cake", dummy: "x" },
{ _id: 6, subject: "ice cream", dummy: "x" },
{ _id: 7, subject: "coffee and cream", dummy: "x" }
]
)
我们正在向文本索引添加虚拟字段。
db.articles.createIndex( { subject: "text", dummy:"text" } )
我们将x 添加到查询中:
db.articles.find( { $text: { $search: "x -cream -cake" } } ).projection({"dummy":0})
没有禁言cream和cake的结果是这样的:
{
"_id" : 4,
"subject" : "baking"
},
{
"_id" : 2,
"subject" : "Coffee Shopping"
},
{
"_id" : 1,
"subject" : "coffee"
}
【讨论】: