2016-03-31 2 views
1

Я немного потерян в запросе субдокументов.Найти документ с несколькими соответствующими поддоменами

Рассмотрим следующий набор вещей:

{ 
name: "thing1", 
gadgets: 
[ 
{ 
    name: "gadget1", 
    components: [ 
     { 
      name: "component1" 
      properties: 
       [ 
        {id: "I1", value: "V1"}, {id: "I2", value: "V2"}, 
        {id: "I3", value: "V3"}, {id: "I4", value: "V2"},... 
       ] 
     }, 
     { 
      name: "component2" 
      properties: 
       [ 
        {id: "I1", value: "V1"}, {id: "I2", value: "V4"}, 
        {id: "I3", value: "V3"}, {id: "I4", value: "V5"},... 
       ] 
     } 
    ] 
}, 
{ 
    name: "gadget2", 
    components: [ 
     { 
      name: "component1" 
      properties: 
       [ 
        {id: "I1", value: "V1"}, {id: "I2", value: "V3"}, 
        {id: "I3", value: "V3"}, {id: "I4", value: "V2"},... 
       ] 
     }, 
     { 
      name: "component2" 
      properties: 
       [ 
        {id: "I1", value: "V1"}, {id: "I2", value: "V7"}, 
        {id: "I3", value: "V1"}, {id: "I4", value: "V2"},... 
       ] 
     } 
    ] 
} 
] 
} 

Я хочу, чтобы запросить коллекцию и получить все то, что содержит устройства с именем «gadget1» и содержит в массиве компонентов документ с именем «COMPONENT1 », то„component1“-subdocumnent должен также содержать в свойствах массива обоих документов:

{id: "I1", value: "V1"} and {id: "I2", value: "V2"}. 

возможно ли это с помощью запроса?

Я попытался с помощью следующего запроса:

{ "$and": [{"gadgets.name": "gadget1"}{"gadgets.properties.id": "I1", "gadgets.properties.value": "V1"},{"gadgets.properties.id": "I2", "gadgets.properties.value": "V2"}]} 

Но без успеха.

ответ

1

Так что здесь есть пара вещей. Это на самом деле случай для $and, и это часто не требуется, но это необходимо, когда вам нужно несколько условий на одном пути объекта. А также, чтобы соответствовать несколько свойств на Массив поддокументе вам нужно $elemMatch:

db.collection.find({ 
    "$and": [ 
    { 
     "components.properties": { 
     "$elemMatch": { 
      "id": "I1", "value": "V1" 
     } 
     }   
    }, 
    { 
     "components.properties": { 
     "$elemMatch": { 
      "id": "I2", "value": "V2" 
     } 
     }   
    } 
    ] 
}) 

Это покажет вам, где документ имеет «как» элементы массива в "components.properties", которые фактически соответствуют оба набору условий.


Думая о том, что больше, вы можете использовать $all здесь, в сочетании с $elemMatch:

db.collection.find({ 
    "components.properties": { 
     "$all": [ 
      { "$elemMatch": { 
       "id": "I1", "value": "V1" 
      }}, 
      { "$elemMatch": { 
       "id": "I2", "value": "V2" 
      }} 
     ] 
    } 
}) 

И это гораздо чище и читаемый формат. $all - это в основном другая форма $and, которую вы можете использовать, чтобы указать условие на том же ключе, которое относится к этому конкретному формату.

Смежные вопросы