2013-01-31 2 views
2

MongoDb의 쿼리 및 업데이트 선택기의 정글에 조금 얽혀 있습니다.다른 필드가 MongoDB의 값과 일치하는 경우에만 배열의 필드를 업데이트하는 방법

상황 : 회사 컬렉션이 있습니다. 이 같은 smth

Companies.find({}) => 
{_id: 1, item_amount: 5}, 
{_id: 2, item_amount: 7}, 
{_id: 3, item_amount: 10} 

그리고 우리는 어떤 구조로 사용자 컬렉션이 있습니다. 사용자는 모든 항목을 사고 싶어하고 기업의 가치를 낮추고 사용자의 증가를 하나의 조건으로 - 사용자가 어디에서 항목을 살 수 있는지 알 수 있습니다.

{userId: _id, 
ownedItems: 
    [{company_id: 2, item_amount: 3}, 
    {company_id: 1, item_amount: 5}] 
} 

확인. 사용자가 {_id: 3}, 예를 들어, 5 개 항목을 구입하려는 경우 내가) (Users.update 수있는 방법,

을 (사용자가 company_id: 3에 대한 필드가있는 경우 우리가 모르는) 나는 다음과 같이 떨어지게 될 수있다 생각 :

&
Users.update({userId: _id}, {$set: {'ownedItems[x].company_id': 3}, $inc{'ownedItems[x].item_amount': 5})

그러나 원인

Companies.update({_id: 3}, {$inc: {item_amount: - 5}})
& 몇 가지 문제가 있습니다.
각 클린트에 대해 [x]을 어떻게 알 수 있습니까? 정렬? 새로운 회사를 추가해야하는 경우 어떻게해야합니까?
'ownedItems[x].company_id' 필드가없는 경우 $set이 작동합니까?

IF/Else 명세서에서 smth를 확인할 수 있습니다. 예를 들어 $exist 또는 $cond (집계의 경우) 선택자를 사용합니다. 하지만 .find()는 항상 true 또는 false가 아닌 커서 (?)를 반환합니다. 그래서 무엇을 할 수 있을까요? 집계 선택기는 어떻게 사용할 수 있습니까? 이처럼 :

Users.find({_id: userId}, {$cond: [{$eq: ['owenedItem[x].company_id', _someId_]}, {$set:{...}}, {$push: {...}}]})

그것은 작동합니까? 당신은 '$'위치 연산자와 관련하여 $ elemMatch 연산자를 사용하려면 같은

답변

3

는 소리 :

http://docs.mongodb.org/manual/reference/operator/elemMatch/ http://docs.mongodb.org/manual/reference/operator/positional/

것은의 당신의 예를 보자. "company_id"가 3 인 사용자의 "ownedItems"목록에서 요소를 찾고 해당 요소의 "item_amount"를 5로 업데이트하려고한다고 가정 해 봅시다.

$ elemMatch 연산자를 사용하면 쿼리하는 목록의 요소를 명시 적으로 나타냅니다. 그런 다음 일치 항목에 $ 연산자를 사용하여 일치하는 요소를 참조하고 변경 한 항목을 변경할 수 있습니다.

사용자의 "ownedItems"목록에 { "company_id": 3}과 일치하는 항목이없는 경우 위의 업데이트는 아무 것도 수행하지 않습니다.그렇게되면, 당신과 같이 새 항목을 추가 할 $ addToSet 연산자와 두 번째 업데이트를 수행 할 수 있습니다 그 대답

Users.update({ userId: _id }, 
       { $addToSet : { ownedItems : { company_id : 3, item_amount : 5 } } }) 

http://docs.mongodb.org/manual/reference/operator/addToSet/

+0

감사합니다! 그러나 나는 몇 가지를 놓칠 수 있습니다. 여기에 내 문제에 대한 2 가지 문제가 있습니다. 첫째, 사용자 컬렉션에'company_id'가 있는지 모르겠습니다. 따라서 사용자 문서에 필드가 없으면 어떻게됩니까? 그리고 두 번째 '문제'는 ** ** ** 연산자에 익숙하지 않을 수도 있지만 쿼리의 배열에 ** 첫 번째 ** 일치를 반환한다고 생각하므로 배열에서 값을 증가시킬 수 있습니다. 예를 들어 company_id = 1 인 경우 쿼리에 대한 첫 번째 일치 항목 일 것입니다 (미안한 질문은 유감스럽게 생각합니다 :))? – Pruntoff

+0

좋은 지적! 이 경우 2 개의 업데이트를 수행해야합니다. 앞에서 언급 한 원래 업데이트의 결과를 확인할 수 있으며, 쿼리가 일치하지 않아 실제로 변경되지 않으면 $ addToSet을 사용하여 ownedItems 목록에 새 항목을 추가하는 다른 업데이트를 수행하십시오. 내 대답을 세부 정보로 업데이트하겠습니다. 두 번째 질문을 이해할 수 있는지 잘 모르겠습니다. 목록에서 첫 번째 일치 항목을 증가시키는 것이 문제입니까? 목록에있는 여러 항목이 동일한 company_id를 갖기를 기대합니까? – robert

관련 문제