我的MongoDB文档具有如下结构:
{
"sentence 0":{
"chunk":["some text",
"text",
"abc"]
},
"sentence 1":{
"chunk":["some text",
"this is a perfect thing",
"abc"]
}
}
我需要在chunk
sentence X
的{{1}}中找到所有包含“完美”字样的文档。
到目前为止,我得到了这个,这是错误的,因为它甚至没有搜索所有sentence
字段。
db.collection.find({"Sentence 0":{ $elemMatch: {"$regex": ".*perfect.*"}}}).limit(10)
答案 0 :(得分:1)
那些是不数组,因此$elemMatch
不适用,因为它仅用于实际数组,也用于"多个"标准而不是一个条件。
它们实际上是"子文件"由" key"指定。因此,您的路径必须准确无误:
db.collection.find({ "sentence 1.chunk": { "$regex": ".perfect." }})
如果你想要两条"路径"你需要一个$or
:
db.collection.find({
"$or": [
{ "sentence 0.chunk": { "$regex": ".perfect." }},
{ "sentence 1.chunk": { "$regex": ".perfect." }}
]
})
为了做到这一点"没有"使用$where
在JavaScript逻辑中执行查询的特定路径:
db.collection.find(function() {
return Object.keys(this).filter(k => /^sentence/).some(k => {
return this[k].chunk.some(ch => /.*perfect.*/)
})
})
这两种情况都非常糟糕,因为您正在使用$regex
搜索不是"锚定"使用插入符^
作为字符串的开头。作为这样一个"完整的集合扫描"执行是为了匹配而不是使用任何可用的索引。相同的约束适用于$where
。
因此结构不是很好。相反,你应该使用"真正的数组"这可以代表一致的路径"要搜索的数据:
{
"sentences": [
{
"chunk": [ "some text",
"text",
"abc"
]
},
"chunk": [ "some text",
"this is a perfect thing",
"abc"
]
}
]
}
然后我们实际上至少可以在特定路径创建索引和查询:
db.collection.find({
"sentences.chunk": { "$regex": "^some" }
})
或者"真实的单词"然后实际使用"sentences.chunk"
上的文字索引,并使用$text
db.collection.find({
"$text": {
"$search": "something"
}
})
但是,由于文字搜索的工作原理,当然这与"the"
或"and"
之类的内容不匹配。
这一切都取决于你的真实"用例。但是你应该至少避免使用"命名键"来构建文档。哪些有特定路径"因为它们本身就不适合查询目的。
N.B 关键名称中的空格也是不好的做法。它可能看起来像人类可读的#34;但你问的是机器"阅读它比你要求的人类更多?#34;明白它。标签名称与构建数据的方式是分开的。