Как сделать запрос в этой структуре вложенного документа (MongoDB)? - PullRequest
4 голосов
/ 11 октября 2011

(Извините, если это тривиальный вопрос.)

У меня есть документы, которые выглядят так (синтаксис Python):

{
  '_id': SomeObjectId,
  'features': [ 
                {'id': 'featureX' , 'value': 6},
                {'id': 'featureY', 'value': 45}
              ]
}

С этой структурой легко найти все документы, которые содержат «featureX» в списке функций. Но я также заинтересован в получении значения, связанного с вложенным документом. Я думаю, что в Python, если я получу документ с запросом, подобным следующему: db.articles.find({'features.id': 'featureX'}), тогда мне нужно будет перебрать массив «features», чтобы найти правильное «значение».

Есть ли другой тип запроса, который может дать мне интересное значение (в этом случае мне не нужно извлекать полный документ, только часть с {'id': 'featureX', 'value': 6 }, который не будет иметь предсказуемого значения индекса в массиве.

PS: Я думаю, что я буду разрабатывать документ по-другому, но мне все еще интересно знать, выполнимо ли приведенное выше задание.

Вот новая структура:

{
'_id': SomeObjectId,
'features': { 
              'featureX': { 'someproperty':'aaa', 'value':6 }, 
              'featureY': {'someproperty' :'bbb', 'value':45} 
            }
}

Есть ли какие-либо проблемы с этим дизайном? В моем случае «featureX», «featureY» уникальны, поэтому их использование в качестве словарей не является проблемой.

Edit: Мне нужно уточнить, что мне нужно будет атомарно обновить слова «featureX» и «featureY» в документе, а MongoDB не поддерживает транзакции . Кроме того, второй дизайн, хотя и не позволяет извлекать вложенный документ, должен облегчать быстрое получение необходимой информации в клиентском коде, предполагая, что я могу запрашивать поддокументы, имеющие определенный ключ.

Я думаю, что этот запрос должен выполнить работу:

result = db.articles.find_one({ 'features.featureX': {'$exists': True} } )
interesting_value = result['features']['featureX']['value']

1 Ответ

2 голосов
/ 11 октября 2011

Я пару раз отвечал о том, что собирал только субдокументы из коллекции монго здесь и здесь

Просто сейчас нет способа сделать это. Это поведение фильтрации многоуровневого внедренного документа, обычно соответствующий фильтр возвращает весь документ, а не подмножества.

В монго уже есть две нерешенные проблемы, связанные с этим позиционным оператором ($) в полях для возврата спецификатора и Возможность использовать данные вложенного документа, содержимое которых использовалось для удовлетворения запроса используя оператор $ . (Пожалуйста, войдите, чтобы проголосовать, если вам действительно нужна функция)

И ваша альтернативная схема здесь тоже не нужна.

поэтому вы должны хранить каждую функцию в отдельном документе, как это, чтобы она работала так, как вы хотели

функция 1

{
'_id': SomeObjectId,
'name' :'some name',
'value': 'feature 1',
'some_field' : 'zzz'
}

функция 2

{
'_id': SomeObjectId,
'name' :'some name',
'value': 'feature 2',
'some_field' : 'zzz'
}

и запрос

db.features.find({'_id':someobjectid})

вернет только конкретную функцию

...