我的文档结构如下:
{
"a": [
{
"b": 1,
"c": "hello world"
},
{
"b": 2,
"c": "boom!"
}
]
}
我在a.c
上有一个文本索引,在a.b
我希望在a.c
a.b
上执行文本搜索的查询
我的等效SQL(对不起,这是我熟悉的地方)是:
select * from table where a.b = 1 and a.c like 'hello'
当我对此数据集执行以下mongo查询时,它不会返回预期结果。
db.inventory.find( { "a": { $elemMatch: { b: 1, c: $text: { search: "hello" } } } } )
我并不是真的希望这种方法有效,但也许在mongo受过良好教育的人可以照亮光明
答案 0 :(得分:2)
$text
运算符适用于a.c
的任何值,因此......
db.inventory.find({'a.b': 1, $text: { $search: "hello" } })
...将与您提供的文档相匹配。
但是,您对$elemMatch
的建议使用建议您希望将这两个谓词应用于a
中的每个子文档,以便仅在a.b = 1
和<}时返回匹配项strong>兄弟 a.c
包含&#34;你好&#34;。
您无法在$text
内使用$elemMatch
,但您可以像这样使用$regex
:
db.inventory.find({ a: { $elemMatch: {'b': 1, 'c': { $regex: /^hello/ }}} })
以上命令将查找至少有一个a
子文档符合 这些条件的文档:
a.b = 1
a.c like "hello%"
如果锚定a.c
的值,则上述命令甚至会使用索引。因此,如果您可以依赖锚定值,则可以在a.c
上停止非文本索引,并且在使用$regex
时,您将获得索引的部分文本搜索。
如果你真的必须有一个文本索引(也许你不能依赖于被锚定的值或者你需要阻塞功能)那么搜索必须分为两部分,使用聚合管道:
db.inventory.aggregate([
{ $match : { $text: { $search: "hello" } } },
{ $match : { 'a.b': 1 } }
])
答案 1 :(得分:0)
除了@ glitching之外,您仍然可以将$ regex与$ text一起使用以获得全文索引:
db.inventory.find( {
"a": { $elemMatch: {
b: 1,
c: { $regex: "hello" }
} }
$text: { $search: "hello" }
} )
答案 2 :(得分:-1)
要对MongoDB数据库执行文本搜索,需要在需要搜索文本的字段上创建文本索引。
文本索引有助于在属于MongoDB数据库集合的字段中搜索文本。
根据以上描述,我创建了一个通配符文本索引。
使用通配符文本索引,MongoDB会为包含集合中每个文档的字符串数据的每个字段编制索引。
db.inventory.createIndex( { "$**": "text" } )
要在a.c上执行文本搜索并在a.b上进行过滤,作为解决方案,请在创建文本索引后尝试执行以下MongoDB查找操作到MongoDB shell。
db.inventory.find({
$text: {
$search: 'hello'
},
a: {
$elemMatch: {
b: 1
}
}
})