Mongoengine查询仅获取已过滤的嵌入文档

时间:2016-02-24 20:27:42

标签: python mongodb aggregation-framework mongoengine

我有这个型号:

class Sub(EmbeddedDocument):
    name = StringField()

class Main(Document):
    subs = ListField(EmbeddedDocumentField(Sub))

当我使用此查询时,它会返回所有Main数据,但我需要subs name'foo'

查询:Main.objects(__raw__={'subs': {'$elemMatch': {'name': 'foo'}}})

例如,使用此数据:

{
  subs: [
          {'name': 'one'}, 
          {'name': 'two'}, 
          {'name': 'foo'}, 
          {'name': 'bar'}, 
          {'name': 'foo'}
        ]
}

结果必须是:

{
  subs: [
         {'name': 'foo'}, 
         {'name': 'foo'}
        ]
}

请注意,在mongodb客户端中,该查询返回此值。

2 个答案:

答案 0 :(得分:0)

如果您允许更改数据模型,请尝试以下操作:

class Main(Document):
    subs = ListField(StringField())

Main.objectsfilter(subs__ne="foo")

我建议这种方法假设嵌入文档只有一个字段,在这种情况下它是多余的。

答案 1 :(得分:0)

MongoEngine提供执行聚合函数的.aggregate(*pipeline, **kwargs)方法。

MongoDB 3.2或更新版

match = {"$match": {"subs.name": "foo"}}
project = {'$project': {'subs': {'$filter': {'as': 'sub',
                                   'cond': {'$eq': ['$$sub.name', 'foo']},
                                   'input': '$subs'}}}}

pipeline = [match, project]
Main.objects.aggregate(*pipeline)

MongoDB版本< = 3.0

{'$redact': {'$cond': [{'$or': [{'$eq': ['$name', 'foo']}, {'$not': '$name'}]},
                       '$$DESCEND',
                       '$$PRUNE']}}
pipeline = [match, redact]
Main.objects.aggregate(*pipeline)