[解決済み] MongoDB select count(distinct x) on indexed column - 大きなデータセットでユニークな結果をカウントする
質問
いくつかの記事やサンプルを見てきましたが、MongoDB でこの SQL クエリを実行する効率的な方法はまだ見つかっていません (ここで、何百万という数の
行
ドキュメントがあります)。
最初の試み
(例:このほぼ重複する質問から -) SQLのSELECT DISTINCTのMongoの等価物? )
db.myCollection.distinct("myIndexedNonUniqueField").length
明らかにデータセットが巨大なので、このエラーが発生しました。
Thu Aug 02 12:55:24 uncaught exception: distinct failed: {
"errmsg" : "exception: distinct too big, 16mb cap",
"code" : 10044,
"ok" : 0
}
二度目の挑戦
グループを作ってみることにしました。
db.myCollection.group({key: {myIndexedNonUniqueField: 1},
initial: {count: 0},
reduce: function (obj, prev) { prev.count++;} } );
しかし、代わりにこんなエラーメッセージが表示されました。
exception: group() can't handle more than 20000 unique keys
3回目の挑戦
まだ試していませんが、いくつかの提案があり、それには
mapReduce
などです。
- これ mongodbでdistinctとgroupをどのように行うか? (不採用、回答者/OPがテストしていない)
- この1 機能別MongoDBグループ (セカンドアテンプトと同じような感じです)
- これ http://blog.emmettshear.com/post/2010/02/12/Counting-Uniques-With-MongoDB
- これ https://groups.google.com/forum/?fromgroups#!topic/mongodb-user/trDn3jJjqtE
- これ http://cookbook.mongodb.org/patterns/unique_items_map_reduce/
また
を修正するプルリクエストがGitHubにあるようです。
.distinct
メソッドがカウントを返すだけであることに言及したプルリクエストがあるようですが、まだ未解決です。
https://github.com/mongodb/mongo/pull/34
しかし、この時点で、私はここで尋ねる価値があると思いました、このテーマに関する最新の情報は何ですか?明確なカウントのために SQL または別の NoSQL DB に移行すべきでしょうか? それとも効率的な方法があるでしょうか?
更新しました。
MongoDB 公式ドキュメントのこのコメントは心許ないのですが、これは正確なのでしょうか?
http://www.mongodb.org/display/DOCS/Aggregation#comment-430445808
更新2です。
新しいAggregation Frameworkが上記のコメントに答えているようです... (MongoDB 2.1/2.2 以上、開発プレビューあり、本番用ではありません)
http://docs.mongodb.org/manual/applications/aggregation/
どのように解決するのですか?
1) 最も簡単な方法は、集約フレームワークを使用することです。 これは 2 つの "$group" コマンドを取ります: 最初のものは異なる値によってグループ化し、2 番目のものは異なる値のすべてを数えます。
pipeline = [
{ $group: { _id: "$myIndexedNonUniqueField"} },
{ $group: { _id: 1, count: { $sum: 1 } } }
];
//
// Run the aggregation command
//
R = db.runCommand(
{
"aggregate": "myCollection" ,
"pipeline": pipeline
}
);
printjson(R);
2) もしこれをMap/Reduceで行いたい場合は、行うことができます。 最初のフェーズでは、キーに対応するすべての異なる値のリストで新しいコレクションを構築します。 第二段階では、この新しいコレクションに対して count() を実行します。
var SOURCE = db.myCollection;
var DEST = db.distinct
DEST.drop();
map = function() {
emit( this.myIndexedNonUniqueField , {count: 1});
}
reduce = function(key, values) {
var count = 0;
values.forEach(function(v) {
count += v['count']; // count each distinct value for lagniappe
});
return {count: count};
};
//
// run map/reduce
//
res = SOURCE.mapReduce( map, reduce,
{ out: 'distinct',
verbose: true
}
);
print( "distinct count= " + res.counts.output );
print( "distinct count=", DEST.count() );
map/reduceの結果をインラインで返すことはできないことに注意してください。なぜなら、それは16MBのドキュメントサイズ制限をオーバーする可能性があるからです。 あなたは は 計算結果をコレクションに保存して、コレクションのサイズをcount()するか、mapReduce()の戻り値から結果の数を取得することができます。
関連
-
[解決済み】MongoDBシェルですべてのコレクションを一覧表示するには?
-
[解決済み] Mongo Restart Error -- /var/run/mongodb/mongod.pid が存在する
-
[解決済み] mongodb aggregation sort
-
[解決済み] 配列フィールドが空でない MongoDB レコードを検索する
-
[解決済み] MongoDB: 1つのコマンドで複数のドキュメントを更新するには?
-
[解決済み] mongooseを使ってmongodbにドキュメントを挿入し、生成されたidを取得する方法は?
-
[解決済み] MongoDB SELECT COUNT GROUP BY
-
[解決済み] ソート順を指定しない場合、MongoDBはどのようにレコードをソートするのですか?
-
[解決済み] 値が NULL ではないマングースクエリ
-
[解決済み] MongoDb への現在の接続数をチェックする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] mongodb count フィールド/キーごとの明確な値の数
-
[解決済み] MongoDB ドキュメントからフィールドを完全に削除する方法は?
-
[解決済み] MongoDB - 管理者ユーザが認証されていない
-
[解決済み] Mongorestore はファイル "db/collection.bson" をどうしたらいいかわからないため、スキップします。
-
[解決済み] 同じデータベース内でコレクションをコピーする最も速い方法は何ですか?
-
[解決済み] mongodb サーバーに接続しようとすると、mongo コマンドが認識されません。
-
[解決済み] MongoDB: 大文字小文字を区別しないクエリを作ることはできますか?
-
CentOS7に新規インストールしたMongodbの初期設定
-
[解決済み] MongoDb の 2 つのフィールドを比較するクエリ条件
-
[解決済み] MongoDb への現在の接続数をチェックする