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.