Mongo. Как я могу агрегировать, фильтровать и включать массив данных из соответствующих документов?

У меня есть база данных контактов, поддерживаемая mongo, и я пытаюсь найти повторяющиеся записи множеством разных способов.

Например, если 2 контакта имеют одинаковый номер телефона, они помечаются как возможный дубликат, то же самое для электронной почты и т. д.

Я использую MongoDB 2.4.2 на Debian с pyMongo и MongoEngine.

Самое близкое, что у меня есть, это поиск и подсчет записей, содержащих один и тот же номер телефона:

dbh.person_document.aggregate([
    {'$unwind': '$phones'},
    {'$group': {'_id': '$phones', 'count': {'$sum': 1}}},
    {'$sort': SON([('count', -1), ('_id', -1)])}
])

# Results in 
{u'ok': 1.0,
 u'result': [{u'_id': {u'number': u'404-231-4444', u'showroom_id': 5}, u'count': 5},
             {u'_id': {u'number': u'205-265-6666', u'showroom_id': 5}, u'count': 5},
             {u'_id': {u'number': u'213-785-7777', u'showroom_id': 5}, u'count': 4},
             {u'_id': {u'number': u'334-821-9999', u'showroom_id': 5}, u'count': 3}
]}

Таким образом, я могу получить числа, которые являются дубликатами, но я не могу понять, как вернуть массив документов, которые на самом деле содержали эти элементы!

Я хочу видеть такие возвращаемые данные для каждого числа:

# The ObjectIDs of the documents that contained the duplicate phone numbers
{u'_id': {u'number': u'404-231-4444', u'showroom_id': 5}, 
  u'ids': [ObjectId('51c67e322b2192121ec4d8f2'), ObjectId('51c67e312b2192121ec4d8f0')], 
  u'count': 2},

Любая помощь приветствуется!


person Marcel Chastain    schedule 18.07.2013    source источник


Ответы (1)


Ах, будь благословен.

Нашел решение почти дословно в MongoDB — используйте структуру агрегации или mapreduce для сопоставления массива строк в документах (сопоставление профилей) .

Окончательный результат, добавление дополнительных элементов для включения имени:

dbh.person_document.aggregate([
    {'$unwind': '$phones'},
    {'$group': {
        '_id': '$phones',
        'matchedDocuments': {
            '$push':{
                'id': '$_id',
                'name': '$full_name'
                }},
        'num': { '$sum': 1}
    }},
    {'$match':{'num': {'$gt': 1}}}
])
person Marcel Chastain    schedule 18.07.2013