2013-02-17 193 views
33

是否有一個查詢來計算字段在數據庫中包含多少個不同的值。mongodb count每個字段/鍵的不同值的數量

FE我有一個國家的領域,有8種國家值(西班牙,英國,法國等)

如果有人增加了更多的文件,以一個新的國家,我想查詢到返回9.

有沒有簡單的方法然後組和計數?

+1

你看過[aggregation](http://docs.mongodb.org/manual/reference/sql-aggregation-comparison/)框架嗎? – WiredPrairie 2013-02-17 19:44:45

+1

或[map-reduce](http://docs.mongodb.org/manual/applications/map-reduce/)? – WiredPrairie 2013-02-17 19:45:21

+0

[索引列上的[MongoDB select count(distinct x)]可能重複 - 爲大數據集計數唯一結果](http://stackoverflow.com/questions/11782566/mongodb-select-countdistinct-x-on-an-索引的列上唯一的,結果換)。我在那裏發佈了我的答案。 – expert 2015-11-01 20:01:17

回答

91

MongoDB有一個distinct command它返回一個字段的不同值的數組;您可以檢查數組的長度以進行計數。

有一個外殼db.collection.distinct()助手以及:

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

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

太好了,謝謝! – Liatz 2013-02-19 10:29:57

+19

如果你的不同值的數量太高,這實際上並不奏效......如果你正在查看世界上某些人的不同名稱或某事。你有一個可以縮放的答案嗎? – underrun 2014-10-01 18:36:57

+2

1+的長度。我正在努力尋找那樣的東西。謝謝。 – 2015-03-30 13:41:00

5

您可以Mongo Shell Extensions利用。這是一個單一的.js導入,你可以附加到你的$HOME/.mongorc.js,或者編程,如果你也在Node.js/io.js中編碼。

樣品

對於現場的每個不同的值計數出現在任選地通過查詢過濾文檔

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

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

字段參數可以是一個數組字段

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

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

我如何將它導入節點? – 2017-11-03 19:49:29

+0

'require(「./ script.js」)',我想 – evandrix 2017-11-06 17:18:59

+0

是正確的,但我無法獲得裏面的函數。我如何使用它們。它們被定義爲db.protoptype.distinctAndCount – 2017-11-06 18:03:04

46

下面是例如使用聚合的API。使情況複雜化,我們將文檔的數組屬性中的大小寫不敏感的單詞分組。

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

,讓結果如

{ "_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

登錄只爲+此答案。謝謝!順便說一句,如果你正在一個獨特的領域做它,只需刪除展開線。 – 2016-07-08 17:58:12

+0

這個腳本是天才。謝謝。 – 2016-08-03 07:13:53

+0

@RichieRich,'unwind'是必要的,因爲代碼將數組字段的單個值分組,匹配'distinct'的工作方式。 – Paul 2017-02-06 15:14:04

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

將肯定

工作對我來說,它已經奏效。 目前,在MongoDB無法正常工作。

2

隨着MongoDB的3.4.4和更新,您可以利用使用$arrayToObject運營商和$replaceRoot管道來獲得計數。

例如,假設您有一組具有不同角色的用戶,並且想要計算角色的不同計數。您將需要運行下面的總管道:

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

示例輸出

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

要找到在收集field_1不同,但我們需要一些WHERE條件也比我們可以這樣做以下:

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

因此,找到numbe [R不同names從集合,其中年齡> 25將是這樣的:

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

希望它能幫助!

相關問題