2012-12-13 29 views
1

我討厭這種問題,但也許你可以指出我明顯。我正在使用Mongo 2.2.2。集合框架中停止正常工作

我有一個集合(在副本集)與6M文件有字符串字段名爲用戶名我有索引。該指數並不是唯一的,但最近我做出了獨特的評價。突然之後,查詢給了我重複的虛假警報。

db.users.aggregate(
    { $group : {_id : "$username", total : { $sum : 1 } } }, 
    { $match : { total : { $gte : 2 } } }, 
    { $sort : {total : -1} }); 

返回

{ 
     "result" : [ 
       { 
         "_id" : "davidbeges", 
         "total" : 2 
       }, 
       { 
         "_id" : "jesusantonio", 
         "total" : 2 
       }, 
       { 
         "_id" : "elesitasweet", 
         "total" : 2 
       }, 
       { 
         "_id" : "theschoolofbmx", 
         "total" : 2 
       }, 
       { 
         "_id" : "longflight", 
         "total" : 2 
       }, 
       { 
         "_id" : "thenotoriouscma", 
         "total" : 2 
       } 
     ], 
     "ok" : 1 
} 

我測試了樣品採集與幾個文件此查詢,它按預期工作。

+0

您確定唯一索引已成功創建嗎?如果有現有的dups,除非設置了'dropDups:true'選項,否則它將無法創建。參見[docs](http://docs.mongodb.org/manual/core/indexes/#drop-duplicates)。 – JohnnyHK

+0

是的。當我查詢'db.users.find({username:「thenotoriouscma」})'時,我可以看到只有一個文檔。 – expert

回答

2

10gen之一回應在他們的JIRA。

有沒有對這個集合的任何更新?如果是這樣,我會嘗試在管道的前面添加{$ sort:{username:1}}。這將確保您只能看到每個用戶名一次,如果它是唯一的。 如果有更新正在進行,如果聚合因增長而移動,聚合可能會看到文檔兩次。另一種可能性是文檔在被聚合看到後被刪除,並且用相同的用戶名插入了新文檔。

因此,通過username分組幫助之前排序。

+0

+1啊,所以我並不遙遠 - 問題是表掃描與索引 - 索引確保文檔只能看到一次,表掃描不會,並且他們被看到兩次 - 通過添加'$ sort'來使用索引並避免'$ group'的問題 –

0

我想答案可能在於一個事實,即你的$group不使用索引,它只是在做在整個收集的掃描。這些運營商可以在聚合框架使用,目前指數:

$match $sort $limit $skip 

他們將工作如果放在前:

$project $unwind $group 

然而,$group本身不會使用索引。當您進行find()測試時,我打賭您正在使用索引,可能作爲覆蓋索引(您可以通過查看該查詢的explain()進行驗證),而不是掃描該集合。基本上我的理論是你的索引沒有模糊,但你的收藏確實如此。

編輯:這可能是因爲文件被更新/集合中的聚合操作期間移動,因此被認爲是兩次,因爲易受騙的不是原本以爲。

如果添加在流水線可以使用索引,但不會改變送入$group結果前面的操作員,那麼你就可以迴避的問題。

+0

遺憾的是沒有找到返回索引一個文檔以及:(而且側面說明,我就不能,除非我放棄複本創建唯一索引。 – expert

+0

黨.....你可以有一個bug的話,這將是值得的在http://jira.mongodb.org/browse/SERVER上提交 - 如果沒有實際的數據,它很可能很難複製,特別是因爲你提到測試數據的結果如預期那樣工作 - 你可以對它進行消毒嗎? –

+0

是的,我擔心錯誤可能會消失,因爲我注意到幻影文檔列表今天不一樣。我提交了'SERVER-7930'。你能告訴我如何保存數據,以便你們可以在必要時重現它? 「mongodump」足夠了嗎? – expert