10

我有以下模型:

class Like(EmbeddedDocument):
    user = ReferenceField(User,dbref=False)
    date = DateTimeField(default=datetime.utcnow,required=True)
    meta = {'allow_inheritance': False}

class Post(Document):
   name = StringField(max_length=120, required=True)
   likes = ListField(EmbeddedDocumentField(Like))

我想只过滤超过 20 个赞的帖子(ListField 大小大于 20)。我尝试使用以下方式查询:

posts = Post.objects.filter(likes__size_gte=20)
posts = Post.objects.filter(likes_gte=20)
posts = Post.objects.filter(likes__gte=20)
posts = Post.objects.filter(likes__size_gte=20)

它们都不起作用。

但是,如果我使用完全匹配(ListField 大小正好 20 个喜欢)它可以工作:

posts = Post.objects.filter(likes__size=20) 

注释?

4

2 回答 2

17

远非完美的解决方案,但您可以使用原始 mongo 查询和$where运算符,例如:

posts = Post.objects.filter(__raw__={'$where': 'this.likes.length > 20'})

另一种选择,应该更快,但在我看来不太清楚,是检查第 21 个元素是否存在:

posts = Post.objects.filter(likes__21__exists=True)

仅当您使用 MongoDB 2.2+ 时,第二个选项才有效

来源:取自这些答案并应用于 MongoEngine。

于 2014-01-12T11:02:35.380 回答
4

您不能将 $size 用于一系列值。

从 mongo 的网站:

$size 不接受值范围。要根据具有不同数量元素的字段选择文档,请创建一个计数器字段,当您将元素添加到字段时会增加该字段。

这是导致答案的相关问题的链接:在 mongoDB 中删除数组字段大小小于 3 的文档

这是上一个链接链接到的 mongo 页面,该页面在上面的块中提供了文档:http: //docs.mongodb.org/manual/reference/operator/size/#_S_size

尝试按照文本块中的建议添加计数器字段。

于 2013-02-22T03:38:48.050 回答