2016-09-07 6 views
0

Я пытаюсь извлечь все записи (и количество всех записей) для структуры, как в следующем,Монго DB - Второй уровень Поиск - elemMatch

{ 
    id: 1, 
    level1: { 
    level2: 
     [ 
     { 
      field1:value1; 
     }, 
     { 
      field1:value1; 
     }, 
     ] 
    } 
}, 
{ 
     id: 2, 
     level1: { 
     level2: 
      [ 
      { 
       field1:null; 
      }, 
      { 
       field1:value1; 
      }, 
      ] 
     } 
    } 

Мое требование принести количество записей, которые имеют Поле 1 заполнено (по крайней мере один на уровне2). Мне нужно сказать, чтобы получить все идентификаторы или количество таких идентификаторов.

Запрос я использую,

db.table.find({}, 
    { 
     _id = id, 
     value: { 
      $elemMatch: {'level1.level2.field1':{$exists: true}} 
     } 
    } 
}) 

Просьба предложить.

EDIT1: Это вопрос, который я пытался задать в комментарии. Я не смог правильно объяснить комментарий. Следовательно, редактирование вопроса.

{ 
    id: 1, 
    level1: { 
    level2: 
     [ 
     { 
      field1:value1; 
     }, 
     { 
      field1:value1; 
     }, 
     ] 
    } 
}, 
{ 
     id: 2, 
     level1: { 
     level2: 
      [ 
      { 
       field1:value2; 
      }, 
      { 
       field1:value2; 
      }, 
      { 
       field1:value2; 
      } 
      ] 
     } 
    } 
    { 
     id: 3, 
     level1: { 
     level2: 
      [ 
      { 
       field1:value1; 
      }, 
      { 
       field1:value1; 
      }, 
      ] 
     } 
    } 

Запрос мы использовали результаты в

value1: 4 
value2: 3 

Я хочу что-то вроде

value1: 2 // Once each for documents 1 & 3 
value2: 1 // Once for document 2 

ответ

0

Вы можете сделать это с помощью следующего запроса найти:

db.table.find({ "level1.level2" : { $elemMatch: { field1 : {$exists: true} } } }, {}) 

Это будет вернуть все документы, у которых есть поле1 в структуре "level1.level2".

Для вашего вопроса в комментариях, можно использовать следующую агрегацию, чтобы «я должен был вернуть группировку (и соответствующее количество) для значений в field1»:

db.table.aggregate(
    [ 
    { 
     $unwind: "$level1.level2" 
    }, 
    { 
     $match: { "level1.level2.field1" : { $exists: true } } 
    }, 
    { 
     $group: { 
     _id : "$level1.level2.field1", 
     count : {$sum : 1} 
     } 
    } 
    ] 

UPDATE: Для вашего вопроса "'value1 - 2` На уровне2 для документа предположим, что все значения будут одинаковыми для поля1.". Я надеюсь, что я правильно понимаю ваш вопрос, вместо того, чтобы группировать только по значению field1, я добавил документ _id как Xtra группировки:

db.table.aggregate(
    [ 
    { 
     $unwind: "$level1.level2" 
    }, 
    { 
     $match: { 
     "level1.level2.field1" : { $exists: true } 
     } 
    }, 
    { 
     $group: { 
      _id : { id : "$_id", field1: "$level1.level2.field1" }, 
      count : {$sum : 1} 
      } 
    } 
    ] 
); 

UPDATE2: я изменил агрегацию и добавил дополнительную группировку, то агрегация ниже дает вам результаты, которые вы хотите.

db.table.aggregate(
    [ 
    { 
     $unwind: "$level1.level2" 
    }, 
    { 
     $match: { 
       "level1.level2.field1" : { $exists: true } 
      } 
    }, 
    { 
     $group: { 
        _id : { id : "$_id", field1: "$level1.level2.field1" } 
        } 
    }, 
    { 
     $group: { 
        _id : { id : "$_id.field1"}, 
        count : { $sum : 1} 
        } 
    } 
    ] 
); 
+0

Спасибо. Мне было интересно, нужно ли мне возвращать группировку (и соответствующий счетчик) для значений в поле1, как бы это изменить? –

+0

См. Мой обновленный ответ – HoefMeistert

+0

Прошу прощения, если я не понял свой вопрос. Этот запрос будет возвращать следующие в качестве выхода - 'значение1 - 3' То, что я ищу что-то подобное, «value1 - 2' В level2, для документа, предполагается, что все значения будут то же самое для поля1. Но его следует считать одной записью (хотя в одном документе есть несколько циклов для поля1) –

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