2013-09-13 3 views
8

Im Стремление с некоторыми функциями агрегации в mongodb.mongodb aggregate встроенные значения документа

Скажем, у меня есть некоторые документы, как этот

[ 
{ 
    _id: "1", 
    periods: [ 
     { 
     _id: "12", 
     tables: [ 
      { 
       _id: "121", 
       rows: [ 
        { _id: "1211", text: "some text"}, 
        { _id: "1212", text: "some other text"}, 
        { _id: "1213", text: "yet another text"}, 

       ] 
      } 
     ] 
     }, 
     { 
     _id: "13", 
     tables: [ 
      { 
       _id: "131", 
       rows: [ 
        { _id: "1311", text: "different text"}, 
        { _id: "1312", text: "Oh yeah"}      
       ] 
      } 
     ] 
     } 
    ] 
}, 
{ 
    _id: "2", 
    periods: [ 
     { 
     _id: "21", 
     tables: [ 
      { 
       _id: "212", 
       rows: [ 
        { _id: "2121", text: "period2 text"}, 
        { _id: "2122", text: "period2 other text"}, 
        { _id: "2123", text: "period2 yet another text"}, 

       ] 
      } 
     ] 
     } 
    ] 
} 
] 

Теперь я хочу использовать запрос MongoDB, чтобы получить все уникальные тексты для одного конкретного элемента верхнего уровня.

eg agregate все тексты для верхнего _id 1. Это означало бы, что я хочу получить все тексты в обоих подэлементах периода.

ожидается выход будет выглядеть следующим образом:

агрегатных тексты фильтрации на _id: 1

[ 
    "some text", 
    "some other text", 
    "yet another text", 
    "different text", 
    "Oh yeah" 
] 

агрегатных тексты фильтрации на _id: 2

[ 
    "period2 some text", 
    "period2 some other text", 
    "period2 yet another text" 
] 

До сих пор мне удалось агрегировать все тексты, но в конечном итоге в нескольких массивах, и мне не удалось отфильтровать их по идентификатору, используя $ match,

Мой текущий совокупный запрос выглядит следующим образом

[ 
    { "$project" : { "text" : "$periods.tables.rows.text" , "_id" : "$_id"}}, 
    { "$unwind" : "$text"}, 
    { "$group" : { "_id" : "$_id" , "texts" : { "$addToSet" : "$text"}}}, 
    { "$project" : { "_id" : 0 , "texts" : 1}} 
] 

Это дает мне результат loooking что-то вроде этого

{ "texts" : [ 
     [ [ "Some text" , "Some other text" , "yet another text"] , [ "different text" , "oh yeah" ] ], 
     [ [ "period2 some text", "period2 some other text", "period2 yet another text"]] 
    ]} 

Если добавить $ спичку: {_id: 1}, никакие результаты не возвращаются.

Может кто-нибудь, пожалуйста, помогите мне с этим, или укажите мне направление, как его решить. Я искал ресурсы, но, похоже, не нашел хорошей документации о том, как использовать эти совокупные функции. Документы mongodb используют только простые документы.

PS Я знаю, что могу сделать это с помощью mapreduce, но надеялся использовать для этого агрегатную функцию.

ответ

15

разматывает только выходит на один уровень вниз, так что вы должны вызвать столько раз, столько, сколько уровней у вас есть, если вы делаете это как

[ 
    { "$project" : { "text" : "$periods.tables.rows.text" , "_id" : "$_id"}}, 
    { "$unwind" : "$text"}, 
    { "$unwind" : "$text"}, 
    { "$unwind" : "$text"}, 
    { "$group" : { "_id" : "$_id" , "texts" : { "$addToSet" : "$text"}}}, 
    { "$project" : { "_id" : 0 , "texts" : 1}} 
] 

Он будет работать, как вы ожидаете.

+0

Спасибо большое, я не знал, что смогу расслабиться так. – Tommy

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