Условия в Find, 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"
            }
    ]
}

Моя цель - найти все "id" в конкретном "service", скажем, "furniture", т.е. получить такие результаты:

[122,123,124,127]

Но я не могу понять, как оформить условие в

db.collection_name.find()

из-за трудности с условием для 'n'-го элемента в массиве, "impressions[n]":"value".

Один из вариантов — использовать полученную агрегированную операцию "id" для поиска показов для каждого "id" для службы, как это было предложено в ответе на этот вопрос, который я задал ранее: — MapReduce в PyMongo.

Но мне нужен только список различных 'id' в службе, а не впечатления. Пожалуйста, помогите!


person nimeshkiranverma    schedule 17.07.2015    source источник
comment
Не могли бы вы перепроверить свой документ выше? Документ выше имеет 2 поля _uid и 2 поля показов, должны ли они быть 2 отдельными документами?   -  person sheilak    schedule 17.07.2015


Ответы (1)


Вам нужна структура агрегации для получения значимых результатов. Примерно так:

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

Или еще лучше с MongoDB 2.6 или более поздней версии, которая может удалять элементы массива, не имеющие соответствия «до» $unwind с $redact:

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)

Or:

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

Чтобы дать вам:

[122, 124, 127, 123]

Если вы хотите, чтобы он был «отсортирован», добавьте $sort в конце конвейера агрегации или отсортируйте полученный список в коде.

person Blakes Seven    schedule 17.07.2015