2011-08-10 1 views
5

私はこのようなfoo.fooコレクションのシャードを持っている:私はいくつかの文書のアップサート行うとMongoDB-Perlで「コレクションのfard.fooのシャードキーの値fieldidを変更できません」とはどういう意味ですか?

db.runCommand({ shardcollection: "foo.foo", key: { id: 1 } }); 

Can't modify shard key's value fieldid for collection: foo.foo 

私がもし:

$connection->update(
    { id => 42 }, 
    { '$set' => { id => 42 } }, # using the '$set' modifier 
    { upsert => 1, safe => 1 }, 
); 

を私はこの例外を取得修飾子なしでアップサート操作を行います。

$result = $collection->update(
    { id => $args{doc_id} }, 
    { id => 42 },     # regular upsert without modifier 
    { upsert => 1, safe => 1 }, 
); 

私はこのエラーを取得:

cannot modify shard key for collection: foo.foo 

をしかし、私は、代わりにこのようシャードとき:

# 'id' has been changed to '_id' 
db.runCommand({ shardcollection: "foo.foo", key: { _id: 1 } }); 

私は上記と同じアップサートを行うときに、私はこの例外を取得:

can't upsert something without shard key 

"shard key's value fieldid"とは何ですか?

なぜ第2の実施例に示すように、改質剤の有無にかかわらず「ID」を設定アップサートを行うことができないのですか?いずれの場合も

、挿入が正常に動作。それは例外を投げるupsertsです。

答えて

11

2つのこと:

  1. シャードキーは不変です。一度設定すると更新できません。これは、あるシャードから別のシャードにデータを移動する必要があるため、意味があります。したがって、シャードキーである(またはその一部である)フィールドを含む更新は、取得したエラーで失敗します。最初の2つのエラーメッセージは両方とも同じエラーです。

  2. シャードキーなしでシャードされたコレクションに挿入することはできません。再び、これはmongoの視点からは意味をなさない。あなたがシャードキーを提供していないなら、それはどのシャードにどのように分かっているのでしょうか?したがって、upsert操作では、シャードキーをfind "criteria"(つまり、最初のパラメータupdate(criteria, update, upsert, multi))に含める必要がありますが、アップデートされたドキュメントでシャードキーを取得する唯一の正しい方法は "update"ではありません。あなたが気づいたように、許可されていない "更新"パラメータ。

意味がありますか?

+1

私はあなたが言っていることを得ています。しかし、私がupsertの基準部分にidを含め、それを更新部分から除外した場合、レコードが存在しない場合、レコードは基準で指定された "id"で挿入されますか? IDは空白のままですか? – Neil

+1

upsertには、新しく作成されたドキュメントに基準と更新の両方が常に含まれます。はい、あなたの_idが追加されます。 –

+0

@Remon これは実際には真実ではありません。 db.stuff.update({_ id: "foo"}、{bar: "baz"}、true、false) 'を実行し、そのオブジェクトが存在しなかった場合、' {"_id" :ObjectId( "50a368dea3a163f3305d3cb4")、 "bar": "baz"} 'データベース内。少なくともバージョン2.2.1では – ghik

関連する問題