mongodb sayısı alan / anahtar başına farklı değer sayısı


105

DB'de bir alanın kaç farklı değer içerdiğini hesaplamak için bir sorgu var mı?

fe Ülke için bir alanım var ve 8 tür ülke değeri var (İspanya, İngiltere, Fransa, vb.)

Birisi yeni bir ülke ile daha fazla belge eklerse, sorgunun 9 döndürmesini isterim.

Gruplandırıp saymaktan daha kolay bir yol var mı?


2
Toplama çerçevesine baktınız mı ?
WiredPrairie


Yanıtlar:


199

MongoDB, bir alan için farklı değerler dizisi döndüren bir distinctkomuta sahiptir; sayım için dizinin uzunluğunu kontrol edebilirsiniz.

Bir de kabuk db.collection.distinct()yardımcısı var:

> db.countries.distinct('country');
[ "Spain", "England", "France", "Australia" ]

> db.countries.distinct('country').length
4

48
Bu, farklı değerlerin sayınız çok yüksekse gerçekten işe yaramaz ... dünyadaki farklı isimlere veya başka bir şeye bakıyorsanız. ölçeklendiren bir cevabın var mı?
boşalması

3
Uzunluk için 1+. Böyle bir şey bulmakta zorlanıyordum. Teşekkürler.
Adeel Ahmad

Orada neden sayım () kullanmadıklarını da bilmiyorum
Marian Klühspies

1
@ MarianKlühspies - çünkü bu, elemanların sayısını saymak için length özelliğini kullanan bir javascript dizisi.
UpTheCreek

Tam aradığım şey ... TY
Maulzey

114

Toplama API'sinin kullanımına bir örnek. Durumu karmaşıklaştırmak için, belgenin dizi özelliğinden büyük / küçük harfe duyarlı olmayan kelimelere göre gruplandırıyoruz.

db.articles.aggregate([
    {
        $match: {
            keywords: { $not: {$size: 0} }
        }
    },
    { $unwind: "$keywords" },
    {
        $group: {
            _id: {$toLower: '$keywords'},
            count: { $sum: 1 }
        }
    },
    {
        $match: {
            count: { $gte: 2 }
        }
    },
    { $sort : { count : -1} },
    { $limit : 100 }
]);

gibi sonuç veren

{ "_id" : "inflammation", "count" : 765 }
{ "_id" : "obesity", "count" : 641 }
{ "_id" : "epidemiology", "count" : 617 }
{ "_id" : "cancer", "count" : 604 }
{ "_id" : "breast cancer", "count" : 596 }
{ "_id" : "apoptosis", "count" : 570 }
{ "_id" : "children", "count" : 487 }
{ "_id" : "depression", "count" : 474 }
{ "_id" : "hiv", "count" : 468 }
{ "_id" : "prognosis", "count" : 428 }

2
Sadece bu yanıtı + almak için giriş yaptım. Teşekkürler! btw bunu benzersiz bir alanda yapıyorsanız, çözme çizgisini kaldırmanız yeterlidir.
Richie Rich

@RichieRich unwindgereklidir, çünkü kod, nasıl distinctçalıştığıyla eşleşen bir dizi alanının tek tek değerlerini gruplandırıyor .
Paul

@Paul, Richie'nin söylediği şey, eğer gruplama sadece "normal" alan (string, int vb.) Yapılırsa çözme adımına ihtiyacınız olmayacağıdır. Doğru değil mi?
guyarad

@guyarad unwind, dizilerle çalışırken gereklidir.
Paul

Cevap için +1, tam olarak üzerinde çalıştığım şey, ne kadar farklı olursa olsun kendine has cazibesi var ama bu sadece altın :) - yine de verileri filtrelemek için istenen sonuçları elde etmek için kümeler hakkında daha fazla şey okumam gerekiyor
Talha

21

MongoDb 3.4.4 ve daha yenisiyle , sayımları elde etmek için $arrayToObjectoperatör ve bir $replaceRootboru hattı kullanımından yararlanabilirsiniz .

Örneğin, farklı rollere sahip bir kullanıcı koleksiyonunuz olduğunu ve rollerin farklı sayılarını hesaplamak istediğinizi varsayalım. Aşağıdaki toplu ardışık düzeni çalıştırmanız gerekir:

db.users.aggregate([
    { "$group": {
        "_id": { "$toLower": "$role" },
        "count": { "$sum": 1 }
    } },
    { "$group": {
        "_id": null,
        "counts": {
            "$push": { "k": "$_id", "v": "$count" }
        }
    } },
    { "$replaceRoot": {
        "newRoot": { "$arrayToObject": "$counts" }
    } }    
])

Örnek Çıktı

{
    "user" : 67,
    "superuser" : 5,
    "admin" : 4,
    "moderator" : 12
}

Bu sorunun cevabı değil, ancak yine de faydalıdır. Bunun ile karşılaştırıldığında nasıl performans gösterdiğini merak ediyorum .distinct().
Redsandro

9

Sen yararlanabileceğiniz Mongo Shell Extensions . Bu $HOME/.mongorc.js, Node.js / io.js'de kod yazıyorsanız, ekleyebileceğiniz veya programlı olarak ekleyebileceğiniz tek bir .js içe aktarmasıdır.

Örneklem

Her bir farklı alan değeri için, isteğe bağlı olarak sorguya göre filtrelenen belgelerdeki tekrarları sayar.

> db.users.distinctAndCount('name', {name: /^a/i})

{
  "Abagail": 1,
  "Abbey": 3,
  "Abbie": 1,
  ...
}

Alan parametresi bir alan dizisi olabilir

> db.users.distinctAndCount(['name','job'], {name: /^a/i})

{
  "Austin,Educator" : 1,
  "Aurelia,Educator" : 1,
  "Augustine,Carpenter" : 1,
  ...
}

bunu düğüme nasıl aktarırım?
Salmaan P

require("./script.js"), sanırım
evandrix

doğru, ama fonksiyonları içeri alamadım. Onları nasıl kullanırım? Db.protoptype.distinctAndCount
Salmaan P

Deponun benioku .mongorc.jsdosyasında (RTFM! 1 !! 1!) Bir nasıl yapılır bölümü vardır, temel olarak dosyayı ana dizine koyun . Bitti.
Janis F

7

field_1Koleksiyonda farklı bulmak için ama biz WHEREde aşağıdaki gibi yapabileceğimizden farklı bir koşul istiyoruz:

db.your_collection_name.distinct('field_1', {WHERE condition here and it should return a document})

Bu nedenle, names25 yaşın üzerindeki bir koleksiyondan farklı bir sayı bulun :

db.your_collection_name.distinct('names', {'age': {"$gt": 25}})

Umarım yardımcı olur!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.