programing

mongo가 어레이 데이터를 오버서스트할 수 있습니까?

topblog 2023. 5. 28. 19:51
반응형

mongo가 어레이 데이터를 오버서스트할 수 있습니까?

저는 이런 몽고 문서를 가지고 있습니다.

{
    "_id" : ObjectId("50b429ba0e27b508d854483e"),
    "array" : [
        {
            "id" : "1",
            "letter" : "a"
        },
        {
            "id" : "2",
            "letter" : "b"
        }
    ],
    "tester" : "tom"
}

나는 삽입하고 업데이트할 수 있기를 원합니다.array단일 mongo 명령을 사용하고 a 내에서 조건부를 사용하지 않습니다.find()그 다음에 달려라insert()그리고.update()물체의 유무에 따라 다릅니다.

id제가 선택하고 싶은 아이템입니다.이 기능으로 어레이를 업데이트하면 다음과 같습니다.

{
    "id" : "2",
    "letter" : "c"
}

는 사해야합니다를 해야 합니다.$set

db.soup.update({
    "tester":"tom",
    'array.id': '2'
}, {
    $set: {
        'array.$.letter': 'c'
    }
})

배열에 새 개체를 삽입하려는 경우

{
    "id" : "3",
    "letter" : "d"
}

는 사해야합니다를 해야 합니다.$push

db.soup.update({
    "tester":"tom"
}, {
    $push: {
        'array': {
            "id": "3",
            "letter": "d"
        }
    }
})

저는 배열 항목에 대한 일종의 업셋이 필요합니다.

프로그래밍 방식으로 해야 하나요, 아니면 몽고 통화 한 번으로 할 수 있나요?

저도 방금 이 문제에 부딪혔어요.원콜 솔루션을 찾지 못했지만 어레이 요소에 고유한 가치가 있을작동하는 투콜 솔루션을 찾았습니다.사용$pull먼저 에 " 을저먼실고명배열요서제소다거음한를에하행령▁command$push.

db.soup.update({
    "tester":"tom"
}, {
    $pull: {
        'array': {
            "id": "3"
        }
    }
})
db.soup.update({
    "tester":"tom"
}, {
    $push: {
        'array': {
            "id": "3",
            "letter": "d"
        }
    }
})

이것은 문서가 존재하지 않는 경우, 문서가 존재하지만 배열에 항목이 존재하지 않는 경우 및 항목이 존재하는 경우에 작동합니다.

다시 말하지만, 이것은 당신이 무언가를 가지고 있을 때만 작동합니다, 예를 들어.id이 예제의 필드는 배열 요소 전체에서 고유해야 합니다.

MongoDB 2.2에서와 같이 내장형 어레이로 전환되는 옵션을 모르기 때문에 응용 프로그램 코드에서 이를 처리해야 할 것입니다.

내장된 어레이를 일종의 가상 컬렉션으로 취급하려는 경우 어레이를 별도의 컬렉션으로 모델링하는 것이 좋습니다.

내장된 배열 내의 필드 값을 기준으로 업버트를 수행할 수는 없지만 내장된 문서가 아직 존재하지 않는 경우 를 사용하여 삽입할 수 있습니다.

db.soup.update({
    "tester":"tom"
}, {
    $addToSet: {
        'array': {
            "id": "3",
            "letter": "d"
        }
    }
})

그것은 당신의 정확한 일치 사용 사례와 맞지 않습니다.id배열 요소의 값이지만 예상 전류 값을 알고 있는 경우 유용할 수 있습니다.

배열 대신 객체를 사용하도록 문서를 재구성할 수 있는 경우 내장된 문서 집합의 업셋을 얻을 수 있습니다.는 방금 다른 질문에 답변을 드렸지만, 편의를 위해 여기에서 수정하겠습니다.


예제 문서는 다음과 같습니다.

{
    tester: 'tom',
    items: {
        '1': 'a',
        '2': 'b'
    }
}

으로 항목을 id을 '값으로 3을 'c', 를 하게 됩니다.

db.coll.update(
    { tester: 'tom' }, 
    { $set: { 'items.3': 'c' } }
)

이름을 입니다.$exists쿼리 연산자)을(를) 검색해야 합니다.속성 이름을 저장하는 추가 배열 필드를 추가하여 이 문제를 해결할 수 있습니다.이 필드는 일반적으로 인덱싱 및 쿼리할 수 있습니다.업써트는

db.coll.update(
    { tester: 'tom' }, 
    { 
        $set: { 'items.3': 'c' },
        $addToSet: { itemNames: 3 }
    }
)

(참고)$addToSet는 O(n)입니다.) 속성을 제거할 때도 배열에서 끌어와야 합니다.

db.widgets.update(
    { tester: 'tom' }, 
    { 
        $unset: { 'items.3': true },
        $pull: { itemNames: 3 }
    }
)

배열 필터 옵션을 사용하여 할 수 있습니다.여기에서 https://docs.mongodb.com/manual/reference/method/db.collection.update/ #update-arrayfilters를 참조할 수 있습니다.

   db.getCollection('soup').update({'tester':tom}, { $set: { "collection.$[element].letter" : 'c' } },
   {
     arrayFilters: [ { "element.id": 2 } ]
   })

그 질문은 2012년부터입니다.Rob Watts가 논평에서 언급한 mongo 문서인 https://docs.mongodb.com/manual/reference/method/Bulk.find.upsert 을 살펴보았지만 매우 희박합니다.

여기서 답을 찾았습니다: https://stackoverflow.com/a/42952359/1374488

mongo 4.2가 업데이트에서 집계 파이프라인에 대한 지원을 추가함으로써 $set, $concatArrays, $ifNull 및 $filter를 사용하여 한 번의 통화로 이를 통합할 수 있었습니다.

db.soup.updateOne(
  { tester: 'tom' },
  [
    {
      $set: {
        array: {
          $concatArrays: [
            [{ id: '2', letter: 'c' }],
            {
              $ifNull: [
                {
                  $filter: {
                    input: '$array',
                    as: 'item',
                    cond: {
                      $ne: [
                        '$$item.id',
                        '2',
                      ],
                    },
                  },
                },
                [],
              ],
            },
          ],
        },
      },
    },
  ],
)

이것은 다음과 같은 항목을(를)id이라'2'배열에서 일치하는 다른 항목이 없으면 항목을 추가합니다.

언급URL : https://stackoverflow.com/questions/13588342/can-mongo-upsert-array-data

반응형