Как найти минимальное значение повторяющегося подполя с помощью структуры агрегации? - PullRequest
0 голосов
/ 11 сентября 2018

Предположим, у меня есть коллекция с большим количеством документов, которые похожи на это:

{u'_id': ObjectId('5b8e52e340a6648cb2cfd93b'),
 u'acetylation': [],
 u'domains': [{u'e-val': 3.7e-31,
               u'end': 764,
               u'pfam_acc': u'PF02190.13',
               u'pfam_name': u'LON_substr_bdg',
               u'start': 568},
              {u'e-val': 0.00048,
               u'end': 311,
               u'pfam_acc': u'PF07719.14',
               u'pfam_name': u'TPR_2',
               u'start': 279},
              {u'e-val': 0.0012,
               u'end': 90,
               u'pfam_acc': u'PF13428.3',
               u'pfam_name': u'TPR_14',
               u'start': 48},
              {u'e-val': 1.9e-10,
               u'end': 516,
               u'pfam_acc': u'PF13923.3',
               u'pfam_name': u'zf-C3HC4_2',
               u'start': 478},
              {u'e-val': 1.4e-06,
               u'end': 281,
               u'pfam_acc': u'PF14559.3',
               u'pfam_name': u'TPR_19',
               u'start': 221},
              {u'e-val': 5.1e-08,
               u'end': 149,
               u'pfam_acc': u'PF15227.3',
               u'pfam_name': u'zf-C3HC4_4',
               u'start': 123}]
}

Я хочу написать структуру агрегации, которая будет возвращать весь документ, который содержит минимумe-val.Кроме того, некоторые документы не содержат никаких данных в этом поле domain (то есть u'domains': []).До сих пор я пытался:

#~import stuff above #
...
pipeline = [
     {
     "$unwind": "$domain"

     #~ },
     #~ {
     #~ "$project": { "_id": {}, "minimum_E_val": { "$min": "$domain.e-val" } }
     }
   ]

pprint.pprint(list(prot_data_collection.aggregate(pipeline)))

, чтобы размотать domains, но это приводит к пустому списку.Я думаю сначала развернуть domains (не уверен, действительно ли это необходимо), затем $project, чтобы я мог использовать $min и сохранить документ в целости (в отличие от $group), а затем, наконец, вернуть документ.Не совсем уверен, где проверка пустого списка будет входить либо.Как мне это сделать?

1 Ответ

0 голосов
/ 11 сентября 2018

С помощью @Veeram это решение дает мне то, что мне нужно.

pipeline = [
    {"$unwind": "$domains"},
    {"$match": {"$and":[{"domains":{"$ne":[]}} , { "domains.e-val":{"$gt":0}}]}},
    {"$sort":{"domains.e-val":1}},
    {"$limit":1}
    ]


pprint.pprint(list(protein_data.aggregate(pipeline)))

1) раскручиваем, чтобы получить каждый элемент массива $ domains в отдельной записи

2)соответствуют для domain.e-val, которые не являются пустыми ([]) и больше чем 0

3), сортируют по domain.e-val в порядке возрастания

4) ограничивают выводпервый документ

...