pymongo - 深度嵌套的objectID

时间:2015-12-18 11:42:47

标签: python mongodb pymongo

我的收藏品如下:

bp_points_to_base

我正在使用此代码获取db.attributes.find({"name" : {"en-UK" : "Fabric"}}).pretty(); { "_id" : ObjectId("5550dab4a14c9766418ff2dc"), "values" : { "source" : [ { "code" : 1, "_id" : ObjectId("5550dab4a14c9766418ff2bf"), "name" : { "fr-FR" : "Coton", "it-IT" : "Cotone", "en-UK" : "Cotton", "es-ES" : "Algodón" } }, { "code" : 2, "_id" : ObjectId("5550dab4a14c9766418ff2c0"), "name" : { "fr-FR" : "Viscose", "it-IT" : "Viscosa", "en-UK" : "Viscose", "es-ES" : "Viscosa" } }, { "code" : 3, "_id" : ObjectId("5550dab4a14c9766418ff2c1"), "name" : { "fr-FR" : "Coton peigné", "it-IT" : "Cotone pettinato", "en-UK" : "Combed Cotton", "es-ES" : "Algodón peinado" } }, { "code" : 4, "_id" : ObjectId("5550dab4a14c9766418ff2c2"), "name" : { "fr-FR" : "Polyester", "it-IT" : "Poliestere", "en-UK" : "Polyester", "es-ES" : "Poliéster" } }, { "code" : 5, "_id" : ObjectId("5550dab4a14c9766418ff2c3"), "name" : { "fr-FR" : "Tencel© Lyocell", "it-IT" : "Tencel© Lyocell", "en-UK" : "Tencel© Lyocell", "es-ES" : "Tencel© Lyocell" } }, { "code" : 6, "_id" : ObjectId("5550dab4a14c9766418ff2c4"), "name" : { "fr-FR" : "Coton peigné biologique", "it-IT" : "Cotone pettinato biologico", "en-UK" : "Combed Organic Cotton", "es-ES" : "Algodón peinado orgánico" } }, { "code" : 7, "_id" : ObjectId("5550dab4a14c9766418ff2c5"), "name" : { "fr-FR" : "Viscose de bambou", "it-IT" : "Viscosa di bamboo", "en-UK" : "Bamboo Viscose", "es-ES" : "Viscosa de bambú" } }, { "code" : 8, "_id" : ObjectId("5550dab4a14c9766418ff2c6"), "name" : { "fr-FR" : "Coton biologique", "it-IT" : "Cotone biologico", "en-UK" : "Organic Cotton", "es-ES" : "Algodón orgánico" } }, { "code" : 9, "_id" : ObjectId("5550dab4a14c9766418ff2c7"), "name" : { "fr-FR" : "Polyester recyclé", "it-IT" : "Poliestere riciclato", "en-UK" : "Recycled Polyester", "es-ES" : "Poliéster reciclado" } }, { "code" : 10, "_id" : ObjectId("5550dab4a14c9766418ff2c8"), "name" : { "fr-FR" : "Modal", "it-IT" : "Modal", "en-UK" : "Modal", "es-ES" : "Modal" } }, { "code" : 11, "_id" : ObjectId("5550dab4a14c9766418ff2c9"), "name" : { "fr-FR" : "Lycra Elastane", "it-IT" : "Lycra élasthanne", "en-UK" : "Lycra Elastane", "es-ES" : "Licra Elastano" } }, { "code" : 12, "_id" : ObjectId("5550dab4a14c9766418ff2ca"), "name" : { "fr-FR" : "Coton issu de culture biologique, recyclé pré-consommation", "it-IT" : "Cotone coltivato biologicamente riciclato pre-consumo", "en-UK" : "Recycled pre-consumer cotton organically grown", "es-ES" : "Algodón orgánico reciclado pre-consumo" } }, { "code" : 13, "_id" : ObjectId("5550dab4a14c9766418ff2cb"), "name" : { "fr-FR" : "Polyester recyclé post-consommation", "it-IT" : "Poliestere riciclato post-consumo", "en-UK" : "Recycled post-consumer polyester", "es-ES" : "Polyéster recilado post-consumo" } }, { "code" : 14, "_id" : ObjectId("5550dab4a14c9766418ff2cc"), "name" : { "fr-FR" : "Élasthanne", "it-IT" : "Elasthan", "en-UK" : "Elastane", "es-ES" : "Elastano" } } ], "name" : [ { "_id" : ObjectId("5550dab4a14c9766418ff2cd"), "name" : { "en-UK" : "3-ply Loopback" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2ce"), "name" : { "en-UK" : "Brushed 2-ply" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2cf"), "name" : { "en-UK" : "Brushed 3-ply" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d0"), "name" : { "en-UK" : "Canvas Weave" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d1"), "name" : { "en-UK" : "Fine Jersey" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d2"), "name" : { "en-UK" : "Fleece" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d3"), "name" : { "en-UK" : "Interlock" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d4"), "name" : { "en-UK" : "Jersey" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d5"), "name" : { "en-UK" : "Piqué" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d6"), "name" : { "en-UK" : "Plain weave" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d7"), "name" : { "en-UK" : "Rib" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d8"), "name" : { "en-UK" : "Sheer Jersey" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2d9"), "name" : { "en-UK" : "Supersoft Jersey" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2da"), "name" : { "en-UK" : "Twill weave" } }, { "_id" : ObjectId("5550dab4a14c9766418ff2db"), "name" : { "en-UK" : "Woven Twill" } } ] }, "name" : { "en-UK" : "Fabric" } }

fabric.name

但我得到错误

  

pymongo.errors.OperationFailure:命令SON([('聚合',u'属性'),('管道',[{' $匹配':{' name.en-UK':' Fabric'}},{' $ unwind':' $ values' },{' $ project':{' valueId':' $ values._id',' name':' $ values .name'}},{' $ match':{' $和':[{' name.en-UK':' Jersey& #39;}]}}])])失败:异常:$ unwind:字段路径末尾的值必须是数组

我想返回def get_attribute_fabric(name): attribute_fabric_meta = db.attributes.aggregate([{ '$match': {'name.en-UK': 'Fabric'} }, { '$unwind' : '$values' }, { '$project': { 'name' : '$values.name', 'valueId': '$values._id'} }, { '$match': { '$and': [ {'name.en-UK': str(name)} ] } }])

任何建议非常感谢

2 个答案:

答案 0 :(得分:0)

您无法在'values'上放松,因为它不是数组。您必须在'values.source'上展开,而是尝试使用此聚合管道,

[
  { '$match': {'name.en-UK': 'Fabric'} },
  { '$unwind' : '$values.source' },
  { '$project': { 'name' : '$values.source.name', 'valueId': '$values.source._id'} },
  { '$match': {'name.en-UK': str(name)}}
]

我也不认为$和那里是必需的。保持简单的伙伴:)

答案 1 :(得分:0)

如果您使用的是MongoDB 3.2或更高版本,您可以使用$filter运算符来高效地执行此操作:

def get_attribute_fabric(name):
    pipeline = [{'$match': {'name.en-UK': 'Fabric'}}, 
        {'$project': {'name': {'$filter': {'input': '$values.name', 'as': 'n', 'cond': {'$eq': ['$$n.name.en-UK',  name]}}}}}
    ]
    return db.attributes.aggregate(pipeline)

演示:

>>> from pprint import pprint
>>> pprint(list(get_attribute_fabric('Woven Twill')))
[{'_id': ObjectId('5550dab4a14c9766418ff2dc'),
  'name': [{'_id': ObjectId('5550dab4a14c9766418ff2db'),
            'name': {'en-UK': 'Woven Twill'}}]}]
>>>