5

シャードされた mongo コレクションがあり、150 万を超えるドキュメントがあります。_id 列をシャード キーとして使用し、この列の値は (ObjectId ではなく) 整数です。

Perl ドライバー (挿入、更新、削除、保存) と mongoimport を使用して、このコレクションに対して多くの書き込み操作を行います。

私の問題は、どういうわけか、同じ _id に重複したドキュメントがあることです。私が読んだことから、これは不可能であるべきです。

重複を削除しましたが、他はまだ表示されます。

それらがどこから来たのか、または何から始めるべきかについてのアイデアはありますか? (また、これをより小さなテスト コレクションで複製しようとしましたが、実行する書き込み操作に関係なく、複製は挿入されません)。

4

2 に答える 2

4

これは実際には Perl ドライバーの問題ではなく、シャーディングの特性に関連しています。MongoDB は、作成時に単一のシャードにあるドキュメント間でのみ一意性を強制できるため、デフォルトのインデックスは一意性を必要としません。

MongoDB: シャーディングの構成ドキュメントには、次のような特定の言及があります。

  • コレクションを分割するときは、分割キーを指定する必要があります。コレクションにデータがある場合、mongo は事前にインデックスを作成する必要があります (チャンキング プロセスが高速化されます)。それ以外の場合は、インデックスが自動的に作成されます。

  • {unique: true} オプションを使用して、一意のインデックスがシャード キーのプレフィックスである限り、基礎となるインデックスが一意性を強制するようにすることができます。

  • "unique: true" オプションを使用しない場合、シャード キーは一意である必要はありません。

于 2012-06-28T11:34:57.793 に答える
1

整数 ID の生成をどのように実装しましたか?

MongoDB Web サイトで提案されているようなシステムを使用する場合は、問題ありません。参考のため:

function counter(name) {
    var ret = db.counters.findAndModify({
         query:{_id:name}, 
         update:{$inc:{next:1}}, 
         "new":true, 
         upsert:true});

    return ret.next;
}

db.users.insert({_id:counter("users"), name:"Sarah C."}) // _id : 1
db.users.insert({_id:counter("users"), name:"Bob D."}) // _id : 2

ドキュメント ストアの最新のレコードを読み取って Id を生成し、perl コードで数値をインクリメントしてから、インクリメントされた数値を挿入する場合、タイミングの問題が発生する可能性があります。

于 2012-06-28T10:52:48.780 に答える