2012-09-14 11 views
12

Yuvalanmış nesneler dizisini sıralamanın bir yolunu arıyorum. İşte bir örnek:MongoDB: nesnelerin iç içe geçmiş dizisini sırala

answers: [ 
      {name: 'paul', state: 'RU'}, 
      {name: 'steve', state: 'US'}, 
      {name: 'mike', state: 'DE'}, 
      ... 
     ] 

Ben answers dizinin tüm name bulmak istiyorum şimdi varsayalım, ancak yükselen için bunu sıralama, bunu başarmak nasıl?

cevap

23

Geri almak istediğiniz sırayla depolarım. Ya da müşteri tarafında çekildikten sonra onu sıralayın.

> db.test.insert({answers: [ 
...     {name: 'paul', state: 'RU'}, 
...     {name: 'steve', state: 'US'}, 
...     {name: 'mike', state: 'DE'}]}); 
> db.test.insert({answers: [ 
...     {name: 'paul', state: 'RU'}, 
...     {name: 'steve', state: 'US'}, 
...     {name: 'xavier', state: 'TX'}]}); 

db.test.aggregate([ 
    {$unwind: "$answers"}, 
    {$sort: {"answers.name":1}}, 
    {$group: {_id:"$_id", answers: {$push:"$answers"}}} 
]); 

üretir: Bu iki seçenek de mümkün değilse

, sen aggregation framework kullanabilirsiniz

{ 
    "result" : [ 
    { 
    "_id" : ObjectId("5053b2477d820880c3469364"), 
    "answers" : [ 
     { 
     "name" : "paul", 
     "state" : "RU" 
     }, 
     { 
     "name" : "steve", 
     "state" : "US" 
     }, 
     { 
     "name" : "xavier", 
     "state" : "TX" 
     } 
    ] 
    }, 
    { 
    "_id" : ObjectId("5053af9f7d820880c3469363"), 
    "answers" : [ 
     { 
     "name" : "mike", 
     "state" : "DE" 
     }, 
     { 
     "name" : "paul", 
     "state" : "RU" 
     }, 
     { 
     "name" : "steve", 
     "state" : "US" 
     } 
    ] 
    } 
], 
    "ok" : 1 
} 
-2

bulunan bir şeyi yaptıktan sonra() Eğer dönüş değeri sıralama() kullanabilirsiniz.

db.collection.find({},{"answers.name":1}).sort({"answers.name":1}) 

Bulma, koleksiyondaki tüm belgelerin ad alanlarını ayıklar. Bu sıralama onları daha sonra, ada göre sıralayarak sıralar.

http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order

+1

"" answer.name "anahtarlarınızla ilgili tırnaklara ihtiyacınız var. Ama senin kodunun ne aradığını düşünmüyorum ... –

+4

Örneğiniz tüm belgeleri, her dizideki ilk adla sıralanan '_id 'alanı ve' name' dizisiyle listeler. 'Sort()' belge düzeyinde çalışır ve belgeler içindeki dizileri yeniden sıralamaz. – Stennie

4

Bu, bu bağlamda yararlı olmayabilir, ama ben bu eklemek düşündüm. Ayrıca, birden fazla şekilde sıralamak zorunda kalmayacağınız, denormalize edilmiş koleksiyonlar için daha iyi olma eğiliminde olan yazının üzerine yazma seçeneğiniz de vardır.

Kullanıcıda bir bildirim oluştururken bu durumu uygulamamda buldum.

Meteor.users.helpers({ 
    'addToFeed': function (gameId, pushData) { 
    check(pushData, FeedSchema); 
    Meteor.users.update({ 
     _id: this._id, 
     "games.gameId": gameId 
    }, { 
     $push: { 
     "games.$.feed": { 
      $each: [pushData], 
      $sort: { timestamp: -1 } 
     } 
     } 
    }); 
    } 
}); 

O zamana find() kullanabilirsiniz çünkü oldukça kullanışlı olduğu tespit ve varsayılan olarak özelliklerine göre sıralanacaktır.

+0

$ adlı alanı ayarlayamamakla ilgili bir minimongo hatası alıyorum ... Herhangi bir fikir var mı? Bence bu istediğim şeye çok yakın. – lol