2016-10-30 1 views
0

Давайте, например, следующие коллекции:PyMongo- выбора поддокументы из коллекции с помощью регулярных выражений

{ 
    '_id': '0', 
    'docs': [ 
     {'value': 'abcd', 'key': '1234'}, 
     {'value': 'abef', 'key': '5678'} 
    ] 
} 
{ 
    '_id': '1', 
    'docs': [ 
     {'value': 'wxyz', 'key': '1234'}, 
     {'value': 'abgh', 'key': '5678'} 
    ] 
} 

Я хочу, чтобы иметь возможность выбрать только поддокументы под списке «Документы», которые «значения» содержит строку 'ab'. Что я ожидаю получить это следующие коллекции:

{ 
    '_id': '0', 
    'docs': [ 
     {'value': 'abcd', 'key': '1234'}, 
     {'value': 'abef', 'key': '5678'} 
    ] 
} 
{ 
    '_id': '1', 
    'docs': [ 
     {'value': 'abgh', 'key': '5678'} 
    ] 
} 

Таким образом, отфильтровывать несовпадающие поддокументы.

+0

Пожалуйста, добавьте то, что вы пробовали до публикации. – Veeram

ответ

0

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

from pprint import pprint 
from bson import Regex 

regex = Regex(r'ab') 
pprint(list(col.aggregate([{ 
    '$unwind': '$docs' 
}, { 
    '$match': {'docs.value': regex} 
}, { 
    '$group': { 
     '_id': '$_id', 
     'docs': {'$push': '$docs'} 
    } 
}]))) 

Я предполагаю, что «Col» является переменным, указывающим на ваш объект PyMongo Collection. Эти выходы:

[{u'_id': u'1', 
    u'docs': [{u'key': u'5678', u'value': u'abgh'}]}, 
{u'_id': u'0', 
    u'docs': [{u'key': u'1234', u'value': u'abcd'}, 
      {u'key': u'5678', u'value': u'abef'}]}] 

«г» префикс строки делает это «сырая» строка Python, чтобы избежать каких-либо проблем с регулярными выражениями кода. В этом случае регулярное выражение просто «ab», поэтому префикс «r» не нужен, но сейчас это хорошая практика, поэтому вы не ошибаетесь в будущем.

+1

Это возвращает только первое совпадение в конкретной коллекции. Мне нужен выбор, чтобы включать любые другие совпадения, таким образом изменяя вывод, чтобы включить {'значение': 'abef', 'key': '5678'} – 0rka

+0

О, хорошая точка. «find» не может этого сделать до тех пор, пока не будет реализована https://jira.mongodb.org/browse/SERVER-6612, поэтому я обновил свой ответ, чтобы вместо этого использовать структуру агрегации. –

+0

Соответствует моим потребностям. Спасибо! – 0rka