【问题标题】:Getting a dictionary inside a list by key in mongoDB (mongoengine)在mongoDB(mongoengine)中按键获取列表中的字典
【发布时间】:2013-06-28 08:28:24
【问题描述】:

我在我的 Flask 应用程序 (mongoengine) 中使用 mongoDB (mongoHQ)。 我有一个看起来像这样的Document

{items: [{id: 1}, {id: 2}, {id: 3}]}

有没有办法在单个查询中使用id: 1 访问例如dict

目前我正在使用next() 语句循环遍历items 列表,我希望有一个更明智的解决方案。谢谢

【问题讨论】:

    标签: python mongodb mongoengine


    【解决方案1】:

    我不熟悉 MongoEngine,但 $ 投影运算符可以过滤数组以仅显示匹配的元素。在 Mongo shell 中:

    > db.foo.insert({"items": [{"id": 1}, {"id": 2}, {"id": 3}]})
    > db.foo.find({'items.id': 1}, {'items.$': true})
    { "_id" : ObjectId("51ce29b68b178484ff2a01ed"), "items" : [  {  "id" : 1 } ] }
    

    更多信息:http://docs.mongodb.org/manual/reference/projection/positional/

    在 MongoEngine 中您似乎可以这样做:

    Foo.objects(__raw__={'items.id': 1}).only('items.$')
    

    更多:http://mongoengine-odm.readthedocs.org/en/latest/guide/querying.html#raw-queries

    【讨论】:

    • 是的,我遇到了这个,但遗憾的是我无法让它与 mongoengine 一起使用。不过谢谢
    • 我整个上午都在尝试您所建议的各种变化,但无济于事。它输出关于'items.$' 部分的错误。如果我排除它,我只会得到一个<Foo object>,而我真正想要的是字典。不过谢谢
    • 这是错误顺便说一句:'str' object has no attribute 'db_field'
    【解决方案2】:

    在 DB 查询或 python 语句中?

    使用python:

    In [21]: d = {"items": [{"id": 1}, {"id": 2}, {"id": 3}]}
    
    In [22]: [i for i in d["items"] if i["id"] == 1]
    Out[22]: [{'id': 1}]
    

    (将[0]添加到列表comp的末尾以获取字典)

    也可以使用生成器:

    In [23]: (i for i in d["items"] if i["id"] == 1)
    Out[23]: <generator object <genexpr> at 0x052A1D50>
    
    In [24]: _.next()
    Out[24]: {'id': 1}
    

    我个人会按照上述方式进行操作,因为我们正在处理从数据库返回的记录。

    如果你想直接提取字段(假设我们只想要返回的第一个包含{"id":1} 的文档):

    In [35]: class Doc(Document):
        ...:     items = ListField(DictField())
        ...:     
    
    In [36]: newdoc = Doc(items=[{"id":1},{"id":2},{"id":3}])
    
    In [37]: newdoc.save()
    Out[37]: <Doc: Doc object>
    
    In [38]: for document in [d for d in Doc.objects(items__id=1).first().items if d["id"]==1]:
        ...:     print document
        ...:     
    {u'id': 1}
    

    仅提取匹配的字典更难,因为字段 实际上是字典列表。您不会通过修改查询以仅返回匹配的字段部分来节省任何速度,因此请返回完整字段并从 python 中获取您想要的位。相同的速度,更易于维护。

    【讨论】:

    • 谢谢,但我的意思是在查询中。正如我所提到的,我可以通过在 python 中进行操作来获得我需要的东西。
    • 修正了从数据库中提取匹配记录的版本,但是在数据库端拼接记录的返回字段以仅显示匹配部分会比在 python 端更慢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 2011-12-22
    • 2010-11-19
    相关资源
    最近更新 更多