2012-02-22 9 views
6

これは顧客を表すドキュメントであるとします。mongodbインデックスの埋め込みフィールド(ドット表記)

{ 
    company_name: 'corporate ltd.', 
    pocs: [ 
     {name: 'Paul', email: '[email protected]'}, 
     {name: 'Jessica', email: '[email protected]'} 
    ] 
} 

私は、だから私は、次のコマンドを発行したpocs.email の一意のインデックスを定義したい:

db.things.ensureIndex({"pocs.email": 1}, {unique: true}) 

奇妙なことは、電子メールを持つPOCと別の会社を追加しようとしたときにはすでに存在しているということです別の会社では、独特のインデックス制約を尊重して、mongoはこれを拒否します。ある

は、以下が存在することはできません。大丈夫です

{ 
    company_name: 'corporate ltd.', 
    pocs: [ 
     {name: 'Paul', email: '[email protected]'}, 
     {name: 'Jessica', email: '[email protected]'} 
    ] 
}, 
{ 
    company_name: 'contoso llc', 
    pocs: [ 
     {name: 'Paul', email: '[email protected]'}, 
    ] 
} 

を。ただし、同じ文書内に重複したpocを持つことは可能です。

{ 
    company_name: 'corporate ltd.', 
    pocs: [ 
     {name: 'Paul', email: '[email protected]'}, 
     {name: 'Paul', email: '[email protected]'}, 
     {name: 'Jessica', email: '[email protected]'} 
    ] 
}, 

私のCLIは、以下のシーケンスをコマンドを参照してください。

> version() 
version: 2.0.2 
> 
> use test 
switched to db test 
> db.test.ensureIndex({"poc.email": 1}, {unique: true}) 
> 
> db.test.insert({company: "contoso", poc: [{email: '[email protected]'}]}) 
> db.test.insert({company: "contoso", poc: [{email: '[email protected]'}]}) 
E11000 duplicate key error index: test.test.$poc.email_1 dup key: { : "[email protected]" } 
> ({company: "contoso", poc: [{email: '[email protected]'}, {email: '[email protected]'}]}) 
> 
> 
> db.test.find() 
{ "_id" : ObjectId("4f44949685926af0ecf9295d"), "company" : "contoso", "poc" : [ { "email" : "[email protected]" } ] } 
{ "_id" : ObjectId("4f4494b885926af0ecf9295f"), "company" : "contoso", "poc" : [ { "email" : "[email protected]" }, { "email" : "[email protected]" } ] } 

また、これはinsertで、またはupdateのいずれかで起こります。

> db.test.update({"_id" : ObjectId("4f44949685926af0ecf9295d")}, {$push: { poc: {email: '[email protected]'}}}) 
> db.test.find() 
{ "_id" : ObjectId("4f4494b885926af0ecf9295f"), "company" : "contoso", "poc" : [ { "email" : "[email protected]" }, { "email" : "[email protected]" } ] } 
{ "_id" : ObjectId("4f44949685926af0ecf9295d"), "company" : "contoso", "poc" : [  {  "email" : "[email protected]" }, {  "email" : "[email protected]" }, {  "email" : "[email protected]" } ] } 
> 

これは私がマニュアルにスポッティング逃しバグまたはバイ・デザイン・機能ですか?

答えて

7

同じ問題に関する未解決の問題がありますunique indexes not enforced within array of single document。あなたはそれに投票することができます。

また、この同様のポストUnique indexes on embedded documents

にカイル・バンカーによって提案された素敵な回避策があるアップデート

これは、埋め込みフィールドにのみ関連していない、我々はあまりにも、配列フィールドに対して同じことを再現することができます。

>db.uniqqueTest.insert({a:[1],x:1}) 
>db.uniqqueTest.createIndex({a:1}, {unique: true}) 
> db.uniqqueTest.find() 
{ "_id" : ObjectId("4f44c6252434860b44986b02"), "a" : [ 1 ],"x":1 } 

と私たちは(正しい動作)

> db.uniqqueTest.insert({a:[1],x:3}) 
E11000 duplicate key error index: stack.uniqqueTest.$a_1 dup key: { : 1.0 } 

同じ値で新しい文書を作成しようとする。しかし、我々は、アレイ内の同じ値を入れた場合、これは正常に動作している場合、それはエラーをスローします(なしエラーは、黙ってこの

ため

> db.uniqqueTest.insert({a:[2],x:2}) 
> db.uniqqueTest.update({x:2},{$push:{a:2}}) 
{ "_id" : ObjectId("4f44c65f2434860b44986b05"), "a" : [ 2, 2 ], "x" : 2 } 

でもない)、配列内の重複する値を受け入れ10

+2

+1。これはバグと見なされますが、かなり奇妙なものです。 "ユニークなインデックスは、1つのドキュメントにそのキーがあることを強制するように設計されています。 技術的には、これは事実ですが、ほとんどの人がこの機能を使用する方法では、サブドキュメントを含めることが一意です。彼らがそれを修正できるかどうかは疑問です。なぜなら、それはかなりの意味の変化であり、それは一部の人々を傷つけるかもしれないからです。 – Thilo

+0

@ティヒョー、私はあなたに完全に同意します。彼らがそれを受け入れて、ユニークなインデックスの性質を完全に矛盾させるならば、大きな変化になるでしょう。ほとんどの人は、組み込み/サブ文書の概念を実際の文書として誤解していました。それは本当の問題です。しかし、 '埋め込みdocは入れ子にされたプロパティを持つただ一つのフィールドであり、通常のフィールドと同じ特徴しか持たない。彼らがこれを理解していれば、これらの疑問は起こらないでしょう。 – RameshVel

+0

@RameshVel多分、概念を理解するのではなく、視点の問題です。ネストされた配列にN個の項目がある場合は、項目ごとに1つずつ、N個の項目がインデックス表に表示されるようになりました。レコードごとにインデックス定義ごとに単一エントリを作成する「ユニークインデックスの性質」とは異なります。 それよりも、サブ文書を取り出して別のコレクションに配置する場合は、古典的なRDBMSから知っている結合地獄に戻ってください。 –

関連する問題