从文档中检索单个属性

时间:2012-08-27 09:45:09

标签: python mongodb

大家好日子。 假设我们有一个集合和一个看起来像这样的文档:

    test_doc = {
    "ID" : "123",
    "a" : [
                    {
                        'x' : "/",
                        'y' : "2000",
                        'z' : "1000"
                    },
                    {
                        'x' : "/var",
                        'y' : "3500",
                        'z' : "3000"
                    }
           ]

      }

我需要的是检索单个属性a.z。 在MongoDB中,我使用以下查询:

db.testcol.find({"ID":"123","a.x":"/"},{'a.z':1})

返回:

{ "_id" : ObjectId("skipped"), "a" : [ { "z" : "1000" }, { "z" : "3000" } ] }

正如您所看到的,它会返回所有z属性,但是当条件为{"ID":"123","a.x":"/var"}时,我只需要第一个或第二个属性 所以,问题是:在这种情况下我如何获得单一财产?这只是一个糟糕的设计问题,还是我应该以某种方式处理代码(python)中返回的文档?任何建议将不胜感激。

1 个答案:

答案 0 :(得分:1)

在MongoDB 2.0及更早版本中,这是不可能的。你想要做的是返回数组的特定元素 - 但这不是你的投影实际做的,它只会返回整个数组,然后返回每个数组的z元素。

然而,对于2.2(写下这个答案的rc2),事情变得更好了。您现在可以使用$elemMatch作为投影的一部分(有关详细信息,请参阅SERVER-2238),以便您只撤回所需的数组元素。所以,尝试这样的事情:

db.foo.find({"ID":"123",'a':{$elemMatch:{'x':"/"}}},{_id : 0, 'a.$': 1})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }

或者,只需在投影中使用$ elemMatch,您可能认为它更清晰:

db.foo.find({"ID":"123"},{_id : 0, 'a':{$elemMatch:{'x':"/"}}})
//returns 
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }

所以,现在,至少返回的数组只是一个只包含你想要的条目的数组,你可以简单地引用相关的z元素(不支持子文档上的elemMatch投影)。

最后但并非最不重要的是,在2.2中我们有聚合框架,它可以做的一件事(使用$project运算符)是重塑文档并将子文档和数组元素更改为顶级数组为了得到你想要的结果,你会做这样的事情:

db.foo.aggregate( 
        {$match : {"ID":"123"}},  
        {$unwind : "$a"},  
        {$match : {"a.x":"/"}},  
        {$project : {_id : 0, z : "$a.z"}}
)

结果如下:

{ "result" : [ { "z" : "1000" } ], "ok" : 1 }