[英]Mongodb query combining $text search with $regex
My dilemma is that mongodb $text
searches must match an exact word: eg if trying to match a post with 'testing123' a search for 'test' will not match, but using $regex
will match.我的困境是 mongodb $text
搜索必须匹配一个确切的单词:例如,如果尝试将帖子与“testing123”匹配,则搜索“test”将不匹配,但使用$regex
将匹配。 Now, I want to make use of indexes too, but I also want partial matches.现在,我也想使用索引,但我也想要部分匹配。
My thinking is that I could combine them with an $or
operator, but it is not working.我的想法是我可以将它们与$or
运算符结合起来,但它不起作用。 Is this possible?这可能吗? Each query alone inside the $or
work, but when combining them I get no matches. $or
中的每个查询都单独工作,但是在组合它们时我没有得到任何匹配。
If this is not possible, I have found a pretty good solution, here , but I would like the combined $or
to work if possible, but any other suggestions are welcome.如果这是不可能的,我在这里找到了一个很好的解决方案,但如果可能的话,我希望组合的$or
可以工作,但欢迎任何其他建议。
const posts = await Post.find({
name: { $regex: 'foo', $options: 'i' },
$or: [
{ $text: { $search: text, $caseSensitive: false } },
{ text: { $regex: text, $options: 'i' } },
],
});
One way of doing this is to downcase the text into another field, then use $regex search on that field.这样做的一种方法是将文本小写到另一个字段,然后在该字段上使用 $regex 搜索。
You have text that you want to search for any substring case insensitively:您有文本要不区分大小写地搜索任何 substring:
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.insert({foo:'hello world TESTING123'})
WriteResult({ "nInserted" : 1 })
Step 1: add another field which stores the text in lower case.第 1 步:添加另一个以小写形式存储文本的字段。
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.insert({foo:'hello world TESTING123',foo_lower:'hello world testing123'})
Step 2: add index.第二步:添加索引。
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.createIndex({foo_lower:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"commitQuorum" : "votingMembers",
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1597711723, 7),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1597711723, 7)
}
Step 3: downcase the query to "testing123"第 3 步:将查询小写为“testing123”
Step 4: use $regex.第 4 步:使用 $regex。
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find({foo_lower:{$regex:'testing123'}})
{ "_id" : ObjectId("5f3b2498f885e53d90f30979"), "foo" : "hello world TESTING123", "foo_lower" : "hello world testing123" }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.find({foo_lower:{$regex:'testing123'}}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.foo",
"indexFilterSet" : false,
"parsedQuery" : {
"foo_lower" : {
"$regex" : "testing123"
}
},
"queryHash" : "0D14CC56",
"planCacheKey" : "1974A2D4",
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"foo_lower" : {
"$regex" : "testing123"
}
},
"keyPattern" : {
"foo_lower" : 1
},
"indexName" : "foo_lower_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"foo_lower" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"foo_lower" : [
"[\"\", {})",
"[/testing123/, /testing123/]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "serene",
"port" : 14420,
"version" : "4.4.0",
"gitVersion" : "563487e100c4215e2dce98d0af2a6a5a2d67c5cf"
},
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1597711761, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1597711761, 1)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.