2013-02-17 17 views
33

Czy istnieje zapytanie do obliczania, ile różnych wartości pole zawiera w DB.liczba mongodb liczba odrębnych wartości na pole/klucz

fe mam pole do kraju i istnieje 8 typów wartości krajów (Hiszpania, Anglia, Francja, etc ...)

Jeśli ktoś doda więcej dokumentów z nowego kraju Chciałbym zapytanie do return 9.

Czy jest łatwiejszy sposób niż grupowanie i liczenie?

+1

Przyjrzał się schematowi [aggregation] (http://docs.mongodb.org/manual/reference/sql-aggregation-comparison/)? – WiredPrairie

+1

Lub [map-reduce] (http://docs.mongodb.org/manual/applications/map-reduce/)? – WiredPrairie

+0

Możliwy duplikat [MongoDB select count (distinct x) w indeksowanej kolumnie - policz unikalne wyniki dla dużych zestawów danych] (http://stackoverflow.com/questions/11782566/mongodb-select-countdistinct-x-on-an- indeksowana-kolumna-liczba-unikalnych-wyników-dla). Wysłałem tam swoją odpowiedź. – expert

Odpowiedz

91

MongoDB ma wartość distinct command, która zwraca tablicę różnych wartości dla pola; możesz sprawdzić długość tablicy dla zliczenia.

Jest powłoka db.collection.distinct() pomocnika, a także:

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

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

Świetnie, dziękuję! – Liatz

+19

to nie działa, jeśli twoja liczba odrębnych wartości jest zbyt wysoka ... jeśli patrzysz na różne nazwy ludzi na świecie lub coś takiego. czy masz odpowiedź, która skaluje? – underrun

+2

1+ dla długości. Próbowałem znaleźć coś takiego. Dzięki. –

5

można wykorzystać na Mongo Shell Extensions. Jest to pojedynczy import .js, który możesz dołączyć do swojego $HOME/.mongorc.js lub programowo, jeśli kodujesz również w Node.js/io.js.

próbki

dla każdej odrębnej wartości pola zlicza wystąpienia w dokumentach ewentualnie odfiltrowane przez zapytanie

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

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

parametr pola może być tablicą pól

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

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

w jaki sposób mogę zaimportować to w węźle? –

+0

'require (" ./ script.js ")', Przypuszczam, że – evandrix

+0

prawo, ale nie byłem w stanie uzyskać funkcji w środku. Jak ich używać. Są one zdefiniowane jako db.protoptype.distinctAndCount –

46

Oto przykład użycia agregacji API. Aby utrudnić sprawę, grupujemy według słów kluczowych nieuwzględniających wielkości liter w dokumentach.

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 } 
]); 

które dają Wynik taki jak

{ "_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 } 
+0

Zalogowano się, aby otrzymać + tę odpowiedź. Dzięki! btw, jeśli robisz to na unikalnym polu, po prostu usuń linię rozwijania. –

+0

Ten skrypt jest genialny. Dzięki. –

+0

@RichieRich, 'unwind' jest konieczne, ponieważ kod grupuje poszczególne wartości pola tablicy, które pasują do tego, jak działa' odrębny'. – Paul

0
db.collectionName.distinct("fieldName").length 

zadziała na pewno

W moim przypadku to zadziałało. obecnie, liczba i odrębne razem w MongoDB nie działa.

2

Z MongoDB 3.4.4 i nowsze, można wykorzystać użycie $arrayToObject operatora i $replaceRoot rurociągu, aby uzyskać liczbę.

Załóżmy na przykład, że masz kolekcję użytkowników z różnymi rolami i chcesz obliczyć różne liczby ról.trzeba by uruchomić następującą łączną rurociągu:

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

Przykâadowa

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

Aby znaleźć odrębne w field_1 w kolekcji, ale chcemy niektóre WHERE warunek zbyt niż możemy to zrobić jak następuje:

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

Znajdź numbe r odrębnego names z kolekcji gdzie wiek> 25 będzie jak:

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

Nadzieję, że to pomaga!