2014-12-12 3 views
0

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

Вот структура часть моей коллекции:

_id: ObjectId("W") 
var1: "X", 
var2: "Y", 
var3: "Z", 
comments: { 
    names: [ 
     { 
     number: 1; 
     }, 
     { 
     number: 3; 
     }, 
     { 
     number: 2; 
     } 
    ], 
    field: Y; 
} 

но все мой запрос с db.collection.find().sort({ "comments.names.number": -1 }) не работает.

желаемый результат направление сортировки:

{ "_id" : ObjectId("W"), "var1" : "X", "var3" : "Z", "comments" : { [ { "number" : 3 }, { "number" : 2 },{ "number" : 1 } ], "field": "Y" } } 

Можете ли вы мне помочь?

ответ

1

Вам необходимо агрегировать результат, как показано ниже:

  • Unwind массив имен.
  • Sort записей на основе comments.names.number по убыванию заказать.
  • Group записи, основанные на поле _id.
  • project требуемая структура.

Код:

db.collection.aggregate([ 
{$unwind:"$comments.names"}, 
{$sort:{"comments.names.number":-1}}, 
{$group:{"_id":"$_id", 
      "var1":{$first:"$var1"}, 
      "var2":{$first:"$var2"}, 
      "var3":{$first:"$var3"}, 
      "field":{$first:"$comments.field"}, 
      "names":{$push:"$comments.names"}}}, 
{$project:{"comments":{"names":"$names","field":"$field"},"var1":1, 
      "var2":1,"var3":1}} 
],{"allowDiskUse":true}) 

Если ваша коллекция велика, вы можете добавить $match критериев в начале трубопровода агрегации для фильтрации записей или использовать (allowDiskUse:true), для облегчения сортировки большого количества записей ,

db.collection.aggregate([ 
{$match:{"_id":someId}}, 
{$unwind:"$comments.names"}, 
{$sort:{"comments.names.number":-1}}, 
{$group:{"_id":"$_id", 
      "var1":{$first:"$var1"}, 
      "var2":{$first:"$var2"}, 
      "var3":{$first:"$var3"}, 
      "field":{$first:"$comments.field"}, 
      "names":{$push:"$comments.names"}}}, 
{$project:{"comments":{"names":"$names","field":"$field"},"var1":1, 
      "var2":1,"var3":1}} 
]) 

Что Ниже запрос делает:

db.collection.find().sort({ "comments.names.number": -1 }) 

найти все документы, а затем отсортировать эти документы, основанные на числовом поле в порядке убывания. Что это на самом деле делает для каждого документа, получить значение поля comments.names.number, которое является самым большим для каждого документа. Затем отсортируйте родительские документы на основе этого номера. Он не манипулирует массивом имен внутри каждого родительского документа.

0

MongoDB запросов сортировать результирующие документы, основанные на сборе полей, указанных в этом роде. Они не сортируют массивы в документе. Если вы хотите отсортировать массив, вам нужно отсортировать его самостоятельно после того, как вы извлечете документ, или сохраните массив в отсортированном порядке. См. this old SO answer от Stennie.

+0

Это неправда. Это возможно с использованием структуры агрегации. – BatScream

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