Gun*_*her 6 mongodb pymongo mongodb-query
我正在使用MongoDB搜索包含列表列表的元素,其中列表中的至少一个项目与搜索参数匹配.
这是我目前拥有的结构的一个例子.
{
"Item 1":{
"data":[
["green", 1]
]
},
"Item 2":{
"data":[
["blue", 9],
["green", 1]
]
}
}
Run Code Online (Sandbox Code Playgroud)
我想搜索数据列表中值为"green"的所有项目.
我目前有这个:
my_data.find({'data': {'$in': ['green']}})
Run Code Online (Sandbox Code Playgroud)
但是,没有返回任何结果.
您需要一个"直接路径"到任何查询元素,"数据"不是您需要在此处搜索的路径的"顶层",而是文档中的"项目1"或"项目2","数据"是其中的一个子元素.
基本情况是使用"点符号",其中根元素至少可能存在"已知",并且还注意到$in操作符不必仅仅匹配数组中的值,因为MongoDB不关心.但是你需要一个嵌套的$elemMatch代替:
db.my_data.find({
"$or": [
{ "Item 1.data": {
"$elemMatch": {
"$elemMatch": { "$eq": "green" }
}
}},
{ "Item 2.data": {
"$elemMatch": {
"$elemMatch": { "$eq": "green" }
}
}}
]
})
Run Code Online (Sandbox Code Playgroud)
没有用于匹配前一路径的一部分的"通配符",因此有必要在$or条件内声明完整路径以搜索文档中的每个可能路径.
如果写出所有可能的前缀键是不切实际的,那么您唯一的另一种方法是使用JavaScript评估$where来确定匹配的逻辑:
db.my_data.find(function() {
var doc = this;
delete doc._id;
var matched = false;
for ( k in doc ) {
matched = doc[k].data.some(function(el) {
return el.some(function(inner) {
return inner === "green";
});
});
if (matched) break;
}
return matched;
})
Run Code Online (Sandbox Code Playgroud)
或者使用"数据"数组实际测试可能元素以包含"绿色"值的逻辑的一些变体.这不是一个很好的解决方案,因为$where需要在每个文档上执行以评估条件,因此不能使用索引来过滤结果.这意味着扫描整个集合,基本上是最慢的方法.
也只是显示写入的"shell快捷方式",否则function()内容只是作为$wherepymongo或其他语言驱动程序的参数中的"字符串"提交,但基本上下文是它是在服务器上评估的JavaScript代码.
更好的是更改文档,以便始终存在要查询的元素的一致路径.如:
{
"items": [
{ "name": "Item 1", "data": [["green", 1]] },
{ "name": "Item 2", "data": [["blue", 9], ["green", 1]] }
]
}
Run Code Online (Sandbox Code Playgroud)
然后你可以发出这个简单的查询:
db.my_data.find({ "items.data": { "$elemMatch": { "$elemMatch": { "$eq": "green" } } } })
Run Code Online (Sandbox Code Playgroud)
由于"路径"总是"items.data"允许仅针对该路径的单个条件来测试所有元素
| 归档时间: |
|
| 查看次数: |
3413 次 |
| 最近记录: |