2016-12-01 15 views
0

複数のサブ文書の更新クエリを一度に作成したいと思います。私はすべてのサブ文書のステータスをパッシブに設定します。ここでは、クエリで指定した条件を満たしています。MongoDBで複数のサブ文書を更新またはクエリ

db.deduplications.update( 
{ $and: [ 
    { "_id": "189546D623FC69E3B693FDB679DBC76C" }, 
    { "DeviceVersionPairs.DeviceId": ObjectId("5822d0606bfdcd6ec407d9b9") }, 
    { "DeviceVersionPairs.CloudFolderId": ObjectId("5823110e6bfdd46ec4357582") }, 
    { "DeviceVersionPairs.CloudFileId": ObjectId("582311168cd396223499942a") }, 
    { "DeviceVersionPairs.VersionId": ObjectId("582311168cd396223499942b") } 
] }, 
{ $set: { "DeviceVersionPairs.$.Status": "passive" }}); 

上記のクエリでは、正確に1つのサブ文書が見つかると、必要に応じて更新が行われます。しかし;

db.deduplications.update( 
{ $or: [ { $and: [ 
     { "_id": "189546D623FC69E3B693FDB679DBC76C" }, 
     { "DeviceVersionPairs.DeviceId": ObjectId("5822d0606bfdcd6ec407d9b9") }, 
     { "DeviceVersionPairs.CloudFolderId": ObjectId("5823110e6bfdd46ec4357582") }, 
     { "DeviceVersionPairs.CloudFileId": ObjectId("582311168cd396223499942a") }, 
     { "DeviceVersionPairs.VersionId": ObjectId("582311168cd396223499942b") } 
    ] } , 
    { $and: [ 
     { "_id": "189546D623FC69E3B693FDB679DBC76C" }, 
     { "DeviceVersionPairs.DeviceId": ObjectId("56dfe1356caaea14a819f1e4") }, 
     { "DeviceVersionPairs.CloudFolderId": ObjectId("583fb4bc6e7f341874f13bfc") }, 
     { "DeviceVersionPairs.CloudFileId": ObjectId("583fb539e015b8a53fb71872") }, 
     { "DeviceVersionPairs.VersionId": ObjectId("583fb4ca6e7f331874213584") } 
    ] } ] }, 
{ $set: { "DeviceVersionPairs.$.Status": "passive" }}); 

私はまたはでクエリセグメントを移入し、それがエラーを与える他の項目を追加します

WriteResult({ 
    "nMatched" : 0, 
    "nUpserted" : 0, 
    "nModified" : 0, 
    "writeError" : { 
     "code" : 16837, 
     "errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: DeviceVersionPairs.$.Status" 
    } 
}) 

を私はここで何をしないのですか?

+0

あなたは_id = "189546D623FC69E3B693FDB679DBC76C"のサブドキュメントを更新したいと思いますが、DeviceIdはクエリの2つですが他のサブドキュメントは更新しませんか? –

+0

私はそう思います。他の '_id'が'または 'レベルに存在する可能性があり、すべてのサブ文書がすべての' _id'の更新される必要があるわけではありません。 –

+0

downvoteの理由は何ですか?実際にはここに来て、 '$'位置演算子が複数のサブ文書と一致しないことを知ることができます。これはコミュニティにとって有益なことではありませんか? –

答えて

2

あなたは理由複数のサブ文書と一致する2番目のクエリでこのエラー

The positional operator did not find the match needed from the query

を得ました。現在のところ、位置演算子のを使用して、位置演算子を使用して配列内のすべての項目を更新することはできません。

ので、あなたの問題を解決するために、あなたがこのプロセスに従うことができ

  1. 検索ドキュメント

    を_idを使用して$elemMatch を使用して、サブ文書を検索し、その後

  2. 更新各サブ文書と再び

  3. を文書を保存

このように試すことができます。

db.deduplications.find( 
{ $or: [ { 
     "_id": ObjectId("583fc558668bde730a460e11") , 
     "DeviceVersionPairs":{ 
      $elemMatch:{ "DeviceId": ObjectId("5822d0606bfdcd6ec407d9b9") , 
      "CloudFolderId": ObjectId("5823110e6bfdd46ec4357582") , 
      "DeviceVersionPairs.CloudFileId": ObjectId("582311168cd396223499942a") , 
      "DeviceVersionPairs.VersionId": ObjectId("582311168cd396223499942b") }} 
    } , 
    { 
     "_id": ObjectId("583fc558668bde730a460e11") , 
     "DeviceVersionPairs":{ 
      $elemMatch:{ "DeviceId": ObjectId("56dfe1356caaea14a819f1e4") , 
      "CloudFolderId": ObjectId("583fb4bc6e7f341874f13bfc") , 
      "CloudFileId": ObjectId("583fb539e015b8a53fb71872") , 
      "VersionId": ObjectId("583fb4ca6e7f331874213584") }} 
    } ] 
}).forEach(function (doc) { 
    doc.DeviceVersionPairs.forEach(function (device) { 
     device.status = 'passive'; 
    }); 
    db.deduplications.save(doc); 
}); 
+0

これは私が避けようとしていたものです。私のクエリはすでにこの形になっています。今すぐすべての更新を一度に行うことでパフォーマンスを向上させようとしています。しかし、今はできないと感じています。右? –

+0

はい現在は可能ではありません –

+0

これは私にとって今の答えです。ありがとうございました。 –

0

何が欲しいのか分かりませんが、もし私が正しいとすれば、あなたが望むのは$ elemMatchかもしれません。

MongoDB Update Manualを参照してください

、および

あなたが埋め込まれた文書にしたいクエリ、あなたは$を使用することはできません$elemMatchとし、$または直接、これはMongoDBのの「バグ」のいくつかの種類があります。

+0

'$ elemMatch'で提供したクエリをどのように形成することができますか? –

0

文書を更新するには、UpdateMany()メソッドを使用します。フレームワークとlangauageによれば、この方法は、Update({multi : true});またはすべて更新({})のような異なるであろう。例えば `

db.collection.updateMany(
    <filter>, 
    <update> 
); 

使用$setを書き込みます。

参考:https://docs.mongodb.com/v3.2/reference/method/db.collection.updateMany/

try { 
    db.restaurant.updateMany(
     { $or: [] 
     }, 
     { $set: { "DeviceVersionPairs.$.Status": "passive" } } 
    ); 
} catch (e) { 
    print(e); 
} 
+0

これも機能しません。 –

+0

レコードをフィルタリングしようとしている可能性がありますが正しくない可能性があります。 '_id'を使ってレコードを検索することで、複数のレコードを更新することはできません。 – yojna

+0

は実際にはクエリの '_id'には関係しませんが、' $ 'は位置演算子です。複数のサブ文書と一致することはできません。それは私が今日学んだことです。 –

0

私は、クエリの下に実行しました。そしてそれは素晴らしい仕事です。

db.mm.update({ $or: [ {$and: [{"_id": ObjectId("581d18d41b6c5c752f11c87a")}] }, 
         {$and: [{"_id": ObjectId("581a1a671b6c5c752f11c87b")}] } 
       ] 
      }, {$set : {"name": "abc3"}}); 

最初のドキュメントが見つからない場合は、2番目のドキュメントが更新されます。 1番目のものが見つかった場合は、最初のもののみを更新しています。

あなたの質問には、>エラーメッセージが表示されていることがわかります"nMatched" : 0です。それはどんな文書も見つけられません。すべてのIDと参照IDを確認します。

+0

Idが正しいことを確認できます。私は、あなたと同じように、そのレスポンスが疑わしいので、同じ '{$ or:[]}'クエリで '.find'クエリを作成しましたが、ドキュメントに問題はありません。問題は位置演算子 '$'を使った@shaishab royの発言である。複数のサブ文書と一致することはできません。 –

関連する問題