2017-09-28 93 views
5

Birden çok alanın farklı değerlerini saymaya çalışıyorum Bir MongoDB Toplama sorgusuyla. Ben her alanın ayrı sayımı istiyorumBirden çok alanın mongodb kümelenmesi kullanılarak farklı sayısı

{ 
    "car_type": "suv", 
    "color": "red", 
    "num_doors": 4 
}, 
{ 
    "car_type": "hatchback", 
    "color": "blue", 
    "num_doors": 4 
}, 
{ 
    "car_type": "wagon", 
    "color": "red", 
    "num_doors": 4 
} 

: Ben grup birden çok alana başardı

distinct_count_car_type=3 
distinct_count_color=2 
distinct_count_num_doors=1 

ve sonra ayrı bir sayımını yapmak ancak yalnızca verebilir

Yani burada benim veri var bana ilk alanda bir sayı. Hepsi değil. Ayrıca büyük bir veri kümesi.

cevap

1

!

db.foo.aggregate([ 
    {$project: {x: {$objectToArray: "$$CURRENT"}}} 
    ,{$unwind: "$x"} 
    ,{$match: {"x.k": {$ne: "_id"}}} 
    ,{$group: {_id: "$x.k", y: {$addToSet: "$x.v"}}} 
    ,{$addFields: {size: {"$size":"$y"}} } 
        ]); 

Bu verecektir:

{ "_id" : "num_doors", "y" : [ 4 ], "size" : 1 } 
{ "_id" : "color", "y" : [ "blue", "red" ], "size" : 2 } 
{ 
    "_id" : "car_type", 
    "y" : [ 
     "wagon", 
     "hatchback", 
     "suv" 
    ], 
    "size" : 3 
} 

Sen $project can ya $addFields eklemek veya benzersiz değerleri veya boyutunun kümesini dışlamak için uygun gördüğünüz gibi.

+0

Maalesef, mongodb 3.2 kullanıyorum ve $ objectToArray kullanıyorum. – Deckard

+0

Doğru. Yükseltmeyi 3.4.4'e öneririm. –

+0

Bu yüzden geliştirdim ve çözümünüzü denedim. Şu anda sahip olduğum sorun, farklı bir sayı yapmak istediğim dinamik alanlar aslında bir dizidedir, çünkü başka bir koleksiyondan $ lookup bir arandığından beri. Sorunun en üstündeki koleksiyon, $ lookup nedeniyle sonuçlarımın bir dizisidir. Bu yüzden, bir nesne üzerinde $ objectToArray yapmaya çalıştığımda "$ objectToArray bir belge girişi gerektirir, bulundu: dizi". Ve sonra $ arrayToObject önce $ objectToArray çağırmak için önce denedim ve "$ arrayToObject 'anahtar' ve 'v' bir nesne anahtarları gerektirir olsun. Yanlış sayıda anahtar bulundu: 5". – Deckard

4

aşağıdaki toplu boru hattı çalıştırmanız size istenilen sonucu vermelidir: Sen $objectToArray ... gücü aradığınız

db.collection.aggregate([ 
    { 
     "$group": { 
      "_id": null, 
      "distinct_car_types": { "$addToSet": "$car_type" }, 
      "distinct_colors": { "$addToSet": "$color" }, 
      "distinct_num_doors": { "$addToSet": "$num_doors" } 
     } 
    }, 
    { 
     "$project": { 
      "distinct_count_car_type": { "$size": "$distinct_car_types" }, 
      "distinct_count_color": { "$size": "$distinct_colors" }, 
      "distinct_count_num_doors": { "$size": "$distinct_num_doors" } 
     } 
    } 
]) 
+0

güzel, ayrıca '_id: 0' projeksiyonuna da ekleyebilirsiniz;). –

+0

Bu çalışır. Teşekkürler! Biraz yavaşlar ama çok fazla değil. Yeni bir soru sormam gerekebilir, ancak bu nesneler dinamik bir alandan oluşuyorsa (yani alan adını önceden kodlayamazdım). Haritanızdaki herhangi bir sayıdaki farklı sayıları almanın bir yolu var mı? Bunu nasıl yapabilirim? – Deckard

+1

@Deckard aşağıya bakın. –