【问题标题】:Conditions in Find, MongoFind, Mongo 的条件
【发布时间】:2015-10-07 10:25:09
【问题描述】:

我有一个带有 doc 的 mongo 集合,如下所示:-

{
    "_id" : ObjectId("55a9378ee2874f0ed7b7cb7e"),
    "_uid" : 10,
    "impressions" : [
            {
                    "pos" : 6,
                    "id" : 123,
                    "service" : "furniture"
            },
            {
                    "pos" : 0,
                    "id" : 128,
                    "service" : "electronics"
            },
            {
                    "pos" : 2,
                    "id" : 127,
                    "service" : "furniture"
            },
            {
                    "pos" : 2,
                    "id" : 125,
                    "service" : "electronics"
            },
            {
                    "pos" : 10,
                    "id" : 124,
                    "service" : "electronics"
            }
    ]
},
{
    "_id" : ObjectId("55a9378ee2874f0ed7b7cb7f"),
    "_uid" : 11,
    "impressions" : [
            {
                    "pos" : 1,
                    "id" : 124,
                    "service" : "furniture"
            },
            {
                    "pos" : 10,
                    "id" : 124,
                    "service" : "electronics"
            },
            {
                    "pos" : 1,
                    "id" : 123,
                    "service" : "furniture"
            },
            {
                    "pos" : 21,
                    "id" : 122,
                    "service" : "furniture"
            },
            {
                    "pos" : 3,
                    "id" : 125,
                    "service" : "electronics"
            },
            {
                    "pos" : 10,
                    "id" : 121,
                    "service" : "electronics"
            }
    ]
}

我的目标是在特定的"service" 中找到所有"id",比如"furniture",即得到这样的结果:

[122,123,124,127]

但我无法弄清楚如何在

中构建条件
db.collection_name.find()

因为很难为数组中的第 'n' 个元素设置条件,"impressions[n]":"value"

一种选择是使用获得的"id"s 执行聚合操作来查找服务的每个"id" 的展示次数,正如我之前提出的这个问题的答案所建议的那样:- MapReduce in PyMongo

但我只想要服务中不同的'id' 列表,而不是展示次数。 请帮忙!

【问题讨论】:

  • 您能否再次检查您的上述文件?上面的文档有 2 个 _uid 字段和 2 个“印象”字段,它们应该是 2 个单独的文档吗?

标签: python mongodb mongodb-query pymongo aggregation-framework


【解决方案1】:

您需要aggregration framework 才能获得有意义的结果。就像这样:

result = db.collection.aggregate([
    { "$match": {
        "impressions.service": "furniture"
    }},
    { "$unwind": "$impressions" },
    { "$match": {
        "impressions.service": "furniture"
    }},
    { "$group": {
        "_id": "$impressions.id"
    }}
])

或者更好的是使用 MongoDB 2.6 或更高版本,它可以使用 $redact 删除与 $unwind“之前”不匹配的数组项:

result = db.collection.aggregate([
    { "$match": {
        "impressions.service": "furniture"
    }},
    { "$redact": {
       "$cond": {
           "if": { 
               "$eq": [
                   { "$ifNull": [ "$service", "furniture" ] },
                   "furniture"
               ]
           },
           "then": "$$DESCEND",
           "else": "$$PRUNE"
       }
    }},
    { "$unwind": "$impressions" },
    { "$group": {
        "_id": "$impressions.id"
    }}
])

产量:

{ "_id" : 122 }
{ "_id" : 124 }
{ "_id" : 127 }
{ "_id" : 123 }

不是简单的“列表”,而是对其进行转换,因此:

def mapper (x):
    return x["_id"]

map(mapper,result)

或者:

map(lambda x: x["_id"], result)

给你:

[122, 124, 127, 123]

如果您希望它“排序”,那么要么在聚合管道的末尾添加一个$sort 阶段,要么在代码中对结果列表进行排序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-28
    • 2014-08-17
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    • 2020-07-17
    • 1970-01-01
    相关资源
    最近更新 更多