2015-10-05 20 views
5

Ben şuna benzer mesajların Mongo koleksiyona sahip:Mongo sıralama üzerinde hesaplanan koşul

{ 
    'recipients': [], 
    'unRead': [], 
    'content': 'Text' 
} 

Alıcılar kullanıcı kimlikleri bir dizidir ve okunmamış henüz açmadığınız tüm kullanıcıların bir dizidir mesaj. Yani istediğiniz gibi olup, ancak, ilk 20 sonuç döndürür, böylece tüm mesajların listesini sorgulamak gerekiyor gibi, ilk şey okunmamış olanları öncelik:

db.messages.find({recipients: {$elemMatch: userID} }) 
    .sort({unRead: {$elemMatch: userID}}) 
    .limit(20) 

Ama bu işe yaramaz. Sonuçları belirli bir kritere uyup uymadıklarına göre önceliklendirmenin en iyi yolu nedir? Belirli kriterlere göre hiç "ağırlık" sonuç ya da bir "tür" dahilinde "hesaplanmış değeri" karşı herhangi bir istiyorsanız

cevap

5

, o zaman bunun yerine .aggregate() yöntemi gerekir. Burada

db.messages.aggregate([ 
    { "$match": { "messages": userId } }, 
    { "$project": { 
     "recipients": 1, 
     "unread": 1, 
     "content": 1, 
     "readYet": { 
      "$setIsSubset": [ [userId], "$unread" ] } 
     } 
    }}, 
    { "$sort": { "readYet": -1 } }, 
    { "$limit": 20 } 
]) 

dönüştürülmüş dizi ile "okunmamış" dizinin $setIsSubset operatörün karşılaştırması: Bu hangi belgede sadece mevcut alanı kullanılabilir değerler $sort işlemde kullanılmak üzere "" tahmin sağlar Herhangi bir eşleşme olup olmadığını görmek için [userId]. Sonuç, userId'nin bulunduğu true veya bulunmayan false olacaktır.

Bu daha sonra (bir çeşit is true üstte göre Azalan) maçlara tercih sonuçları sıralar hangi $sort geçirilebilir ve nihayet $limit sadece belirtilen tutara kadar sonuçları döndürür.

Yani "tür" için calulated terimini kullanmak için, değeri üzerine sıralanabilir böylece belgeye "öngörülen" olması gerekiyor. Toplama çerçevesi bunu nasıl yapıyorsunuz?

Ayrıca $elemMatch sadece bir dizi içinde tek değer aynı olması gerekmez unutmayın ve yalnızca ihtiyaç doğrudan değerini belirtmek. Buradaki amaç, "çoklu" koşulların, tek bir dizi elemanında yerine getirilmesi gerektiğidir; tabi ki burada geçerli değildir.

+0

Bu mükemmel bir şekilde çalıştı. Teşekkür ederim! Yapacağım tek yorum, $ setIsSubSet'i $ setIsSubset olarak değiştirene kadar Mongo bir hata attı. – beatniknight

+0

@beatniknight Tipik ben. Belge bağlantısı doğruydu ama camelCase beynim iki kelimeyi söyleyip duruyor ve bu şekilde yazmayı sürdürüyor. –