2015-10-28 2 views
5

я начинаю изучать MongoDB, и я работаю с документами так:Как сгруппировать по первому элементу массива с MongoDB?

{ 
    "_id" : ObjectId("562fac8a4f9ecec40f5b8ff9"), 
    "foo" : { 
     "objectid" : "39", 
     "stuff" : "65" 
    }, 
    "yearpublished" : [ 
     "1979" 
    ], 
    "bar": "1263" 
} 

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

Я уже сделал этот запрос:

db.foobar.aggregate(
    [ 
     { 
     $group : { 
      _id : '$yearpublished', 
      count: { $sum: 1 } 
     } 
     } 
    ] 
) 

и получите:

{ 
    "result" : [ 
     { 
      "_id" : [ 
       "1923" 
      ], 
      "count" : 1.0000000000000000 
     }, 
     { 
      "_id" : [ 
       "1864" 
      ], 
      "count" : 1.0000000000000000 
     } 
} 

Но я ищу такого результата (т.е. первый элемент только):

{ 
    "result" : [ 
     { 
      "_id" : "1923, 
      "count" : 1.0000000000000000 
     }, 
     { 
      "_id" : "1864", 
      "count" : 1.0000000000000000 
     } 
} 

Я пробовал _id : { $first: '$yearpublished.0' }, или _id : { $first: '$yearpublished[0]' }, без успеха.

Знаете ли вы, что я могу группировать по первому элементу массива yearpublished?

ответ

7

К сожалению, сейчас единственный способ сделать это, чтобы извлечь $first элемент из массива после обработки $unwind. Тогда, конечно, вы должны $group снова:

db.foobar.aggregate([ 
    { "$unwind": "$yearpublished" }, 
    { "$group": { 
     "_id": "$_id", 
     "yearpublished": { "$first": "$yearpublished" } 
    }}, 
    { "$group": { 
     "_id": "$yearpublished", 
     "count": { "$sum": 1 } 
    }} 
]) 

Thats единственный текущий способ получить «первый» элемент из массива, деконструирует его и с помощью оператора, чтобы получить запись.

Будущие релизы будут иметь $arrayElemAt, которые могут сделать это с помощью индекса в пределах одной стадии:

db.foobar.aggregate([ 
    { "$group": { 
     "_id": { "$arrayElemAt": [ "$yearpublished", 0 ] }, 
     "count": { "$sum": 1 } 
    }} 
]) 

Но в настоящее время структура агрегации не имеет дело с «точечной нотации» использования индекса, такие как стандартный «проекции» с .find() делает и не будет, следовательно, новыми операциями.

+0

Большое спасибо за этот полный ответ. – Alex

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