MongoDB — запрос по поддереву

#mongodb

#mongodb

Вопрос:

У меня есть структура документа, которая совпадает с упрощенной версией, показанной ниже:

 {
  some_other_props: { ... },
  systems: {
    sys1: {
      score: 24,
      metric: 52
    },
    another_sys: {
      score: 9,
      metric: 77
    },
    some_other_sys: {
      score: 12,
      metric: 5
    }
  }
}
 

Я хотел бы вернуть все документы, где score : { "$gte" : 15 } true для любого из вложенных документов.

Единственный способ, которым я мог подумать об этом, — это получить список ключей system и объединить его в какой-то беспорядок or-statement. Но, похоже, я делаю что-то не так.

Я мог бы переформатировать структуру документа так, чтобы каждая система находилась в своем собственном документе… но в нем много другой информации, some_other_props и переформатирование сейчас было бы проблемой.

По правде говоря, я пытаюсь сделать что-то более сложное. Возвращает все документы, в которых разница между score и одной и metric той же системой сильно отличается. Но прежде чем я смогу это сделать, я хотел убедиться, что могу просто выполнять простые запросы к поддеревьям, как я показал выше.

Кто-нибудь может подсказать, как запрашивать поддеревья в MongoDB?

Ответ №1:

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

 {
  some_other_props: { ... },
  systems: 
    [ {id: 'sys1',
      score: 24,
      metric: 52
    },
    { id: 'another_sys',
      score: 9,
      metric: 77
    }]

}
 

Затем вы можете просто запросить find 'systems.score' : { '$gte' : 15 } , и вы также можете создать индекс для ‘systems.score’, если вы чувствуете, что вам это нужно.

Комментарии:

1. Я не мог понять, как вы можете достичь оценки внутри массива с помощью ваших обозначений? разве это не должно быть systems.$ 0.оценка?

2. systems.$ 0.score будет первым элементом массива., system.score будет соответствовать любому элементу. Смотрите также: mongodb.org/display/DOCS/Multikeys

Ответ №2:

Если вы сейчас точно знаете, что набирает очки, вы можете сделать запрос fat «или» :

 $or : [{ systems.sys1.score : { "$gte" : 15 } }, {systems.another_sys.score : { "$gte" : 15 }}]
 

но это кажется неубедительным способом решения проблемы. итак, мое предложение — создать другой каталог, для system_scores которого есть много ссылок на system_props коллекцию. Это значительно упростило бы запрос.