pymongo - 获取深度嵌套的 objectID
pymongo - getting deeply nested objectID
我有一个像这样的集合:
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
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)}
]
}
}])
但是我得到这个错误
pymongo.errors.OperationFailure: command SON([('aggregate', u'attributes'), ('pipeline', [{'$match': {'name.en-UK': 'Fabric'}}, {'$unwind': '$values'}, {'$project': {'valueId': '$values._id', 'name': '$values.name'}}, {'$match': {'$and': [{'name.en-UK': 'Jersey'}]}}])]) failed: exception: $unwind: value at end of field path must be an array
我喜欢 return objectId
。
非常感谢任何建议
您不能在 '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)}}
]
另外我认为 $and 不是必需的。保持简单,伙计:)
如果您使用的是 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'}}]}]
>>>
我有一个像这样的集合:
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
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)}
]
}
}])
但是我得到这个错误
pymongo.errors.OperationFailure: command SON([('aggregate', u'attributes'), ('pipeline', [{'$match': {'name.en-UK': 'Fabric'}}, {'$unwind': '$values'}, {'$project': {'valueId': '$values._id', 'name': '$values.name'}}, {'$match': {'$and': [{'name.en-UK': 'Jersey'}]}}])]) failed: exception: $unwind: value at end of field path must be an array
我喜欢 return objectId
。
非常感谢任何建议
您不能在 '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)}}
]
另外我认为 $and 不是必需的。保持简单,伙计:)
如果您使用的是 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'}}]}]
>>>