web-dev-qa-db-ja.com

mongodb位置演算子エラー

このようなオブジェクトがあります

{
    "_id" : ObjectId("5742be02289512cf98bf63e3"),
    "name" : "test1",
    "name" : "test1",
    "attributes" : [ 
        {
            "name" : "x",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e8")
        }, 
        {
            "name" : "y",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e7")
        }, 
        {
            "name" : "z",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e6")
        }
    ],
    "__v" : 6
}

そして、すべてのドキュメントを更新し、属性ごとに新しいフィールドを設定します。したがって、単一のクエリを実行して、すべてのドキュメントを一度に更新したいと考えています。このクエリはそれでうまくいくと思います

db.spaces.update({}, { $set: { "attributes.0.weight": 2 } }, {multi: true})

しかし、このクエリを実行すると、エラーが発生します。

"コード":16837、
"errmsg": "位置演算子はクエリから必要な一致を見つけられませんでした。拡張されていない更新:attributes。$。weight"

なぜか分かりません。助けてください

11
Gor

_positional operator_を使用するには、クエリドキュメントの一部として配列フィールドを含める必要があります。

たとえば、最初の配列要素を更新する場合、つまり_{ "attributes.name": "x" }_を使用する場合は、次のパターンに従うことができます。

_db.spaces.update(
   { "attributes.name": "x" }, // <-- the array field must appear as part of the query document.
   { "$set": { "attributes.$.weight": 2 } },
   { "multi": true }
)
_

新しいMongoDBバージョン_3.2.X_の場合、updateMany()メソッドを使用して更新できます上記のフィルターに基づくコレクション内の複数のドキュメント。

22
chridam

位置演算子には、更新クエリの一致部分からの一致が必要です。

例えば:

db.spaces.update({ "attributes.name": "x" }, { $set: { "attributes.0.weight": 2 } }, {multi: true})

ここで、更新操作の最初のパラメーターは配列attributesに一致します。ここで、任意の要素にプロパティname=="x"があります。条件に一致する任意の要素について、位置演算子を使用して更新できます。

したがって、name='x'なので、この場合、最初に一致する要素は、

{
            "name" : "x",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e8")
        }, 

そしてそれは更新されます。

さて、あなたの質問から、各ドキュメントの最初の要素であるattributeweight=2の新しい値を取得するようにドキュメントを更新することを理解しています。

あなたは次のようなことができます

db.spaces.update({ "attributes.name": { $regex: /^(?=[\S\s]{10,8000})[\S\s]*$/ } }, { $set: { "attributes.0.weight": 2 } }, {multi: true})

ここでは、配列属性のすべての要素を照合しています。そして、位置演算子を使用して、その配列の最初の要素を更新します

4
Naeem Shaikh