Python 使用elemmatch和filter执行pymongo查询
我有以下数据结构:Python 使用elemmatch和filter执行pymongo查询,python,mongodb,pymongo,Python,Mongodb,Pymongo,我有以下数据结构: [ { "site_id": ObjectId("5e85b9d20498abd407e9a030"), "status": "ERROR" }, { "site_id": ObjectId("5e85b9d20498abd407e9a120"), "status": "ERROR" }, { "site_id": ObjectId("5e85b9d2049
[
{
"site_id": ObjectId("5e85b9d20498abd407e9a030"),
"status": "ERROR"
},
{
"site_id": ObjectId("5e85b9d20498abd407e9a120"),
"status": "ERROR"
},
{
"site_id": ObjectId("5e85b9d20498abd407e9a030"),
"status": "OK",
"risk_categories": [
{
"position": 1,
"category_id": 1414,
},
{
"position": 2,
"category_id": 1402,
},
{
"position": 3,
"category_id": 1392,
}
]
}
]
我想用pymongo进行如下查询:
集合。查找一个(筛选器=筛选器)
其中:
筛选器={'$and':[{'$and':[{'site_id':ObjectId('5e85b9d20498abd407e9a030')},{'status':'OK'}},{'risk_categories':{'$elemMatch':{'$or':[{'position position':{'eq':1},{'position position':{'eq':2}}}}}}}
但是,它会返回整个对象。不仅仅是我想要的风险类别的价值。
我可以在我的过滤器上做什么来修改它 聚合从
mongo
shell运行:
db.collection.aggregate( [
{
$match: {
site_id: ObjectId('5e85b9d20498abd407e9a030'),
status: "OK"
}
},
{
$addFields: {
risk_categories: {
$filter: {
input: "$risk_categories",
as: "cat",
cond: {
$in: [ "$$cat.position", [ 1, 2 ] ] // this is equivalent to using the "$or"
}
}
}
}
},
] ).pretty()
输出:
{
"_id" : ObjectId("5e85c7b6724e461876467077"),
"site_id" : ObjectId("5e85b9d20498abd407e9a030"),
"status" : "OK",
"risk_categories" : [
{
"position" : 1,
"category_id" : 1414
},
{
"position" : 2,
"category_id" : 1402
}
]
}
使用PyMongo 3.9和MongoDB 4.2,从Python shell:
import pymongo
from pymongo import MongoClient
client = MongoClient()
db = client.test
collection = db.collection
import pprint
from bson.objectid import ObjectId
pipeline = [
{
'$match': {
'site_id': ObjectId('5e85b9d20498abd407e9a030'),
'status': 'OK'
}
},
{
'$addFields': {
'risk_categories': {
'$filter': {
'input': '$risk_categories',
'as': 'cat',
'cond': {
'$in': [ '$$cat.position', [ 1, 2 ] ]
}
}
}
}
},
]
pprint.pprint(list(collection.aggregate(pipeline)))
聚合从
mongo
shell运行:
db.collection.aggregate( [
{
$match: {
site_id: ObjectId('5e85b9d20498abd407e9a030'),
status: "OK"
}
},
{
$addFields: {
risk_categories: {
$filter: {
input: "$risk_categories",
as: "cat",
cond: {
$in: [ "$$cat.position", [ 1, 2 ] ] // this is equivalent to using the "$or"
}
}
}
}
},
] ).pretty()
输出:
{
"_id" : ObjectId("5e85c7b6724e461876467077"),
"site_id" : ObjectId("5e85b9d20498abd407e9a030"),
"status" : "OK",
"risk_categories" : [
{
"position" : 1,
"category_id" : 1414
},
{
"position" : 2,
"category_id" : 1402
}
]
}
使用PyMongo 3.9和MongoDB 4.2,从Python shell:
import pymongo
from pymongo import MongoClient
client = MongoClient()
db = client.test
collection = db.collection
import pprint
from bson.objectid import ObjectId
pipeline = [
{
'$match': {
'site_id': ObjectId('5e85b9d20498abd407e9a030'),
'status': 'OK'
}
},
{
'$addFields': {
'risk_categories': {
'$filter': {
'input': '$risk_categories',
'as': 'cat',
'cond': {
'$in': [ '$$cat.position', [ 1, 2 ] ]
}
}
}
}
},
]
pprint.pprint(list(collection.aggregate(pipeline)))
使用
$elemMatch
投影运算符,您可以对数组元素的字段进行筛选(例如,位置
),但输出将仅显示第一个匹配的数组元素。在已发布的文档中,没有返回两个元素(如position=1或2)的功能。唯一的另一个选项是使用聚合。如果可以使用聚合,我也可以这样做。使用$elemMatch
投影操作符,您可以对数组元素的字段进行筛选(例如,位置
),但输出将仅显示第一个匹配的数组元素。在已发布的文档中,没有返回两个元素(如position=1或2)的功能。唯一的另一个选择是使用聚合。如果可以使用聚合,我也可以这样做。