1

私はこの種の質問は嫌いですが、多分あなたは私に明白なことを指摘することができます。私はMongo2.2.2を使用しています。

インデックスを持つusernameという文字列フィールドを持つ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
}

いくつかのドキュメントを含むサンプルコレクションでこのクエリをテストしましたが、期待どおりに機能します。

4

2 に答える 2

2

10gen の 1 人が JIRA で応答しました。

このコレクションの更新はありますか? もしそうなら、パイプラインの先頭に {$sort: {username:1}} を追加してみます。これにより、ユーザー名が一意である場合に、各ユーザー名が 1 回だけ表示されるようになります。更新が行われている場合、ドキュメントが拡大のために移動すると、集計でドキュメントが 2 回表示される可能性があります。別の可能性として、アグリゲーションによって表示された後にドキュメントが削除され、同じユーザー名で新しいドキュメントが挿入された可能性があります。

usernameそのため、グループ化する前にソートすると役立ちました。

于 2012-12-13T22:06:20.723 に答える
0

I think the answer may lie in the fact that your $group is not using an index, it's just doing a scan over the entire collection. These operators can use and index currently in the aggregation framework:

$match $sort $limit $skip

And they will work if placed before:

$project $unwind $group

However, $group by itself will not use an index. When you do your find() test I am betting you are using the index, possibly as a covered index (you can verify by looking at an explain() for that query), rather than scanning the collection. Basically my theory is that your index has no dupes, but your collection does.

Edit: This likely happens because a document is updated/moved during the aggregation operation and hence is seen twice, not because of dupes in the collection as originally thought.

If you add an operator earlier in the pipeline that can use the index but not alter the results fed into $group, then you can avoid the issue.

于 2012-12-13T10:06:43.557 に答える