2016-08-25 20 views
13

Koleksiyonumdan biri, bazı durumları olan işlemlerin (veya görevlerin) bir listesidir. Örneğin, belgelerin listesi ben new > pending > complete bir statüleri dayalı bu listeyi sıralamak istediğiniz buMongoDB özel bir ifade veya işleve sahip sıralama

{ 
    _id: '57befe57fc956d2e3252890c', 
    task: 'Go buy milk', 
    status: 'pending' 
}, 
{ 
    _id: '57befe5efc956d2e3252890d', 
    task: 'Cook dinner', 
    status: 'complete' 
}, 
{ 
    _id: '57befe5efc956d2e3252890e', 
    task: 'Play games', 
    status: 'new' 
} 

benzeyebilir.

Bunu ek bir alan oluşturmak zorunda kalmadan MongoDB ile nasıl yapabilirim? Benim durumumda olduğu gibi sıralama sırasının önceden konfigüre edilmesi istenebilir (örneğin kullanıcılar tercihlerini pending > new > complete'a sahip olabilir)

+0

Eğer t işleyemez neden olarak bir neden var mı Müşteri tarafında mı sıralama yapıyor? En iyi seçenek, tüm belgeleri döndürmek ve kullanıcı tercih sırasına göre alt grupları oluşturmak için süzgeç kullanmaktır. https://lodash.com/docs#filter – dyouberg

+1

Bunu iki boru hattına sahip bir toplama hattıyla yapabilirsiniz. , '$ project' ve' $ sort'. '$ Project' ekstra bir alan yaratacak, '$ cond' operatörü ile önceden yapılandırılmış bir sıraya göre hesaplanan 'skor', yani 'statü' için yukarıdaki puan için 'yeni' 3 olacak, 2 vb. beklemede, "$ sort" boru hattı skor alanını sıralayacaktır. – chridam

+1

@dyouberg Sayfalama kullanıyorum ve sıralama, sunucu tarafında "$ limit" önce yapılması gerekiyor, aksi halde sayfalandırma tamamen dağınık. Neden tüm öğeleri müşteriye indirmeyi öneriyorsun? Bu bant genişliği ve işlemenin kötü bir kullanımı. –

cevap

6

@chirdam'ın burada neye benzediğini belirttiğine göre. Ayrıca, yeni sıralama alanı istenen şekilde sonuçta mevcut değildir.

DataSet:

{ 
    _id: '57befe57fc956d2e3252890c', 
    task: 'Go buy milk', 
    status: 'pending' 
}, 
{ 
    _id: '57befe5efc956d2e3252890d', 
    task: 'Cook dinner', 
    status: 'complete' 
}, 
{ 
    _id: '57befe5efc956d2e3252890e', 
    task: 'Play games', 
    status: 'new' 
} 

Sorgu:

db.task.aggregate([ 
    { "$project" : { 
     "_id" : 1, 
     "task" : 1, 
     "status" : 1, 
     "order" : { 
      "$cond" : { 
       if : { "$eq" : ["$status", "new"] }, then : 1, 
       else : { "$cond" : { 
        "if" : { "$eq" : ["$status", "pending"] }, then : 2, 
        else : 3 
        } 
       } 
      } 
     } 
    } }, 
    {"$sort" : {"order" : 1} }, 
    { "$project" : { "_id" : 1, "task" : 1, "status" : 1 } } 
]) 

Çıktı:

{ "_id" : "57befe5efc956d2e3252890e", "task" : "Play games", "status" : "new" } 
{ "_id" : "57befe57fc956d2e3252890c", "task" : "Go buy milk", "status" : "pending" } 
{ "_id" : "57befe5efc956d2e3252890d", "task" : "Cook dinner", "status" : "complete" } 
+0

, mevcut alanları tekrar eklemek istemiyorsanız, proje yerine [$ addFields] (https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/) kullanabilirsiniz. – mido

+3

Birden çok başka bir diziden ziyade, istenen sıralamayı bir diziye ekleyebilir ve sıralama alanını oluşturmak için "$ indexOfArray" ifadesini kullanabilirsiniz. Burada bir örnek var: http://www.kamsky.org/stupid-tricks-with-mongodb/using-34-aggregation-to-return-documents-in-same-order-as-in-expression –

+0

@AsyaKamsky you bunu bir cevap olarak eklemeliyim. Eminim ki insanlar yorumunuzu kaçırabilir ve bu oldukça iyi bir çözümdür. –