как найти значения, которые являются общими для разных полей [pymongo aggregate]

63
5

Скажем, у нас есть документы mongodb:

{'shop':'yes'}
{'shop':'ice_cream'}
{'shop':'grocery'}
{'amenity':'yes'}
{'amenity':'hotel'}

Как написать агрегированный запрос в pymongo, который будет возвращать значения, которые являются общими для обоих ключей? В этом примере он должен вернуть "да".

спросил(а) 2015-05-01T14:33:00+03:00 6 лет, 1 месяц назад
1
Решение
88

Конвейер агрегации будет использовать $setIntersection на этапе оператора $project. Это занимает два или более массивов и возвращает массив, содержащий элементы, которые появляются во всех входных массивах. Другим оператором агрегирования, который является полезным, является оператор массива $addToSet который используется при создании отдельного списка значений для каждого сгруппированного поля, которое затем можно сравнить позже.

В mongoshell, вставляя документы

db.collection.insert([
{'shop':'yes'},
{'shop':'ice_cream'},
{'shop':'grocery'},
{'amenity':'yes'},
{'amenity':'hotel'}
])

Вы можете попробовать следующий конвейер агрегации:

db.collection.aggregate([
{
"$group": {
"_id": null,
"shops": {
"$addToSet": "$shop"
},
"amenities": {
"$addToSet": "$amenity"
}
}
},
{
"$project": {
"_id": 0,
"commonToBoth": { "$setIntersection": [ "$shops", "$amenities" ] }
}
}
]);

Выход:

/* 0 */
{
"result" : [
{
"commonToBoth" : [
"yes"
]
}
],
"ok" : 1
}

Пимонго:

>>> pipe = [
... {"$group": { "_id": None, "shops": {"$addToSet": "$shop"}, "amenities": {"$addToSet": "$amenity"}}},
... { "$project": {"_id": 0, "commonToBoth":{"$setIntersection": ["$shops", "$amenities"]}}}
... ]
>>>
>>> for doc in collection.aggregate(pipe):
... print(doc)
...
{u'commonToBoth': [u'yes']}

ответил(а) 2015-05-01T14:51:00+03:00 6 лет, 1 месяц назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема