복붙노트

[MONGODB] MongoDB를 - 업데이트 문서의 배열에 객체 (중첩 된 업데이트)

MONGODB

MongoDB를 - 업데이트 문서의 배열에 객체 (중첩 된 업데이트)

우리는 I에 대한 몇 가지 질문이 다음 모음을 가지고 가정 :

{
    "_id" : ObjectId("4faaba123412d654fe83hg876"),
    "user_id" : 123456,
    "total" : 100,
    "items" : [
            {
                    "item_name" : "my_item_one",
                    "price" : 20
            },
            {
                    "item_name" : "my_item_two",
                    "price" : 50
            },
            {
                    "item_name" : "my_item_three",
                    "price" : 30
            }
    ]
}

- 1 나는 "ITEM_NAME을"에 대한 가격을 높이려는 "my_item_two"그것이 존재하지 않는 경우, 그것은 "항목"배열에 추가해야합니다.

2 - 나는 동시에 두 개의 필드를 업데이트 할 수있는 방법. 예를 들어, "my_item_three"의 가격을 증가시키고, 동시에 (동일한 값)은 "전체"를 증가시킨다.

나는 그렇지 않으면 내가 클라이언트 측 (파이썬)에서 문서를로드하고 업데이트 된 문서를 구성하고 MongoDB를의 기존로 교체 할 필요는 MongoDB의 측면에서이 작업을 수행하는 것을 선호합니다.

최신 정보 이것은 내가 시도 무엇이고 목적이있는 경우 잘 작동합니다 :

db.test_invoice.update({user_id : 123456 , "items.item_name":"my_item_one"} , {$inc: {"items.$.price": 10}})

그러나 키가 존재하지 않는 경우는 아무것도 실시하지 않습니다. 또한 그것은 단지 중첩 된 개체를 업데이트합니다. 뿐만 아니라 "전체"필드를 업데이트하려면이 명령을 수있는 방법은 없습니다.

해결법

  1. ==============================

    1.질문 # 1를 들어, 두 부분으로 그것을 깰 수 있습니다. 첫째, "items.item_name"가 "my_item_two"동일있는 모든 문서를 증가. 이를 위해 당신은 위치 "$"연산자를 사용해야합니다. 뭔가 같은 :

    질문 # 1를 들어, 두 부분으로 그것을 깰 수 있습니다. 첫째, "items.item_name"가 "my_item_two"동일있는 모든 문서를 증가. 이를 위해 당신은 위치 "$"연산자를 사용해야합니다. 뭔가 같은 :

     db.bar.update( {user_id : 123456 , "items.item_name" : "my_item_two" } , 
                    {$inc : {"items.$.price" : 1} } , 
                    false , 
                    true);
    

    이것은 단지 어떤 배열 (당신이 "ITEM_NAME의"가 "my_item_two"에 동일과 배열에 다른 문서가있을 경우 그래서, 그것은 증가되지 않습니다)의 첫 번째 일치하는 하위 문서를 증가 않습니다. 그러나 이것은 당신이 원하는 수 있습니다.

    두 번째 부분은 까다 롭습니다. 다음과 같이 우리는 "my_item_two"없이 배열에 새 항목을 밀어 수 있습니다 :

     db.bar.update( {user_id : 123456, "items.item_name" : {$ne : "my_item_two" }} , 
                    {$addToSet : {"items" : {'item_name' : "my_item_two" , 'price' : 1 }} } ,
                    false , 
                    true);
    

    질문 # 2의 경우, 답은 쉽다. "my_item_three"를 포함 총 및 문서 item_three의 가격을 증가하려면 동시에 여러 필드에 $의 INC 연산자를 사용할 수 있습니다. 뭔가 같은 :

    db.bar.update( {"items.item_name" : {$ne : "my_item_three" }} ,
                   {$inc : {total : 1 , "items.$.price" : 1}} ,
                   false ,
                   true);
    
  2. ==============================

    2.단일 쿼리에서이 작업을 수행 할 수있는 방법은 없습니다. 당신은 첫 번째 쿼리에서 문서를 검색 할 수 있습니다 :

    단일 쿼리에서이 작업을 수행 할 수있는 방법은 없습니다. 당신은 첫 번째 쿼리에서 문서를 검색 할 수 있습니다 :

    문서가 존재하는 경우 :

    db.bar.update( {user_id : 123456 , "items.item_name" : "my_item_two" } , 
                    {$inc : {"items.$.price" : 1} } , 
                    false , 
                    true);
    

    그밖에

    db.bar.update( {user_id : 123456 } , 
                    {$addToSet : {"items" : {'item_name' : "my_item_two" , 'price' : 1 }} } ,
                    false , 
                    true);
    

    필요 조건 {: "my_item_two"$ 북동} 추가 없습니다.

    또한 멀티 스레드 enviourment에 당신은 한 번에 한 스레드 만 (문서가 발견되지 않은 경우, 경우 INSERT), 그렇지 않으면 두 번째를 실행 삽입됩니다 포함 문서를 복제 할 수 있음을주의해야한다.

  3. from https://stackoverflow.com/questions/10522347/mongodb-update-objects-in-a-documents-array-nested-updating by cc-by-sa and MIT license