$ match(聚合)因ObjectId值而失败

时间:2017-05-04 08:50:42

标签: python mongodb aggregation-framework

我有一个简单的收藏。

> db.y.find({}, {'_id': 1})
{ "_id" : ObjectId("5908e63cd15fa104356eaf64") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf65") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf66") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf67") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf68") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf69") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf6a") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf6b") }

我想操作一个简单的聚合管道(主要简化为解释

我运行这个Mongo shell脚本:

print('find')
result = db.y.find({ '_id': ObjectId("5908e63cd15fa104356eaf64") }, {'_id':1})
while ( result.hasNext() ) { printjson( result.next() ); }

print('aggregate match direct')
result = db.y.aggregate( [ {'$match': {'_id': ObjectId("5908e63cd15fa104356eaf64") } }, {'$project': {'_id': 1}} ] )
while ( result.hasNext() ) { printjson( result.next() ); }

print('aggregate match with $eq')
result = db.y.aggregate( [ {'$match': {'_id': {'$eq': ObjectId("5908e63cd15fa104356eaf64") } } }, {'$project': {'_id': 1}} ] )
while ( result.hasNext() ) { printjson( result.next() ); }

print('aggregate match with $ne')
result = db.y.aggregate( [ {'$match': {'_id': {'$ne': ObjectId("5908e63cd15fa104356eaf64") } } }, {'$project': {'_id': 1}}, {'$limit': 5} ] )
while ( result.hasNext() ) { printjson( result.next() ); }

有了这个结果(绝对正确)

find
{ "_id" : ObjectId("5908e63cd15fa104356eaf64") }
aggregate match direct
{ "_id" : ObjectId("5908e63cd15fa104356eaf64") }
aggregate match with $eq
{ "_id" : ObjectId("5908e63cd15fa104356eaf64") }
aggregate match with $ne
{ "_id" : ObjectId("5908e63cd15fa104356eaf65") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf66") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf67") }
{ "_id" : ObjectId("5908e63cd15fa104356eaf68") }

然后我想将它转换为python,如下所示:

...
print('find')

result = y.find({ '_id': 'ObjectId("5908e63cd15fa104356eaf64")' }, {'_id':1})

for i, o in enumerate(result):
    print(i, o)

print('aggregate match direct')

result = y.aggregate( [ {'$match': {'_id': 'ObjectId("5908e63cd15fa104356eaf64")' } }, {'$project': {'_id': 1} } ] )

for i, o in enumerate(result):
    print(i, o)

print('aggregate match with $eq')

result = y.aggregate( [ {'$match': {'_id': {'$eq': 'ObjectId("5908e63cd15fa104356eaf64")' } } }, {'$project': {'_id': 1} } ] )

for i, o in enumerate(result):
    print(i, o)

print('aggregate match with $ne')

result = y.aggregate( [ {'$match': {'_id': {'$ne': 'ObjectId("5908e63cd15fa104356eaf64")' } } }, {'$project': {'_id': 1} }, {'$limit': 5} ] )

for i, o in enumerate(result):
    print(i, o)

有了这个结果:

find
aggregate match direct
aggregate match with $eq
aggregate match with $ne
0 {'_id': ObjectId('5908e63cd15fa104356eaf64')}
1 {'_id': ObjectId('5908e63cd15fa104356eaf65')}
2 {'_id': ObjectId('5908e63cd15fa104356eaf66')}
3 {'_id': ObjectId('5908e63cd15fa104356eaf67')}
4 {'_id': ObjectId('5908e63cd15fa104356eaf68')}

结论:

$ match操作永远不会考虑ObjectId语法。

如何正确编写?

感谢任何提示

基督教

1 个答案:

答案 0 :(得分:0)

您必须在标准库中使用ObjectId类

from bson.objectid import ObjectId
result = y.find({ '_id': ObjectId("5908e63cd15fa104356eaf64") }, {'_id':1})

Possibly Related

现在匹配和查找字段询问_id是否是名为" ObjectId(" 5908e63cd15fa104356eaf64)"的字符串。但在Python中,您必须首先使用ObjectId Class

指定唯一标识符

您的最后一场比赛实际上是打印所有内容,因为您询问所有_ids是否都不等于字符串" ObjectId(" 5908e63cd15fa104356eaf64)"而不是ObjectId