如何执行嵌套字段的mongoengine查询?

时间:2013-12-04 22:10:12

标签: python django mongodb mongoengine

所以基本上我有这些文件

class Tag(Document):
    name = StringField()
    ...

class Doc(Doument):
    nameTag = ReferenceField(Tag)
    tags = ListField(ReferenceField(Tag))

我想查询具有特定名称的nameTags。所以我认为这个问题在这里得到了回答 How to perform such filter queries in mongoengine on nested dicts or arrays contained in dict with python?

但是当我尝试查询时:

name="Hello"
docs1 = Doc.objects(nameTag__name=name)
docs2 = Doc.objects(tags__name=name)

我收到错误

Cannot perform join in mongoDB: nameTag__name

3 个答案:

答案 0 :(得分:1)

Mongodb没有加入,但您的查询正在尝试跨两个集合进行查询。在这种情况下,您有两个查询。一个用于获取匹配的Tag,然后一个用于查询Doc集合并查找对该Tag的任何引用。

答案 1 :(得分:0)

您可以使用本机Django ORM本身,使用mongodb作为后端,在两个集合中执行连接。因此,您不需要使用Mongoengine。

使用django orm并使用djongo

等连接器连接mongodb

答案 2 :(得分:0)

仅提及所有选项。 @罗斯是正确的。 Mongodb没有联接。但实际上,您有2个选择(不仅只有1个):

  1. (由@Ross描述)
  

您必须执行两个查询。一个获取匹配的标签,然后另一个   查询文档集合并找到对该标记的任何引用。

  1. 进行聚合,mongoengine支持它:

    docs1 = Doc.objects.aggregate(
        {"$lookup": {
            "from": "tag", # Tag collection database name
            "foreignField": "_id", # Primary key of the Tag collection
            "localField": "nameTag", # Reference field
            "as": "nameTag",
        }},
        {"$unwind": "nameTag"},
        {"$match": {"nameTag.name": name}})
    

$unwind是必需的,因为$lookup返回文档列表。但是在您的情况下,每个列表始终只有一个文档,因此您可以毫无疑问地使用此代码。

第二种方法似乎比第一种复杂得多。但是,使用第一种方法,您必须对数据库执行2个查询(第二种方法-仅一个)。在某些情况下,第二种方法会更有效。