복붙노트

[MONGODB] 위치`$ '연산자의 다중 사용은 중첩 된 배열을 업데이트

MONGODB

위치`$ '연산자의 다중 사용은 중첩 된 배열을 업데이트

이 질문에 밀접하게이 일에 관련이와 나는 NoSQL의 컨텍스트에서 스키마 설계에 대하여 주어진 조언을 고려할 것입니다, 그러나 나는 이것을 이해 궁금 해요 :

다음 문서가 있다고 가정 :

    _id : 2      abcd
    name : 2     unittest.com
    paths : 4    
        0 : 3    
            path : 2     home
            queries : 4      
                0 : 3    
                    name : 2     query1
                    url : 2      www.unittest.com/home?query1
                    requests: 4

                1 : 3    
                    name : 2     query2
                    url : 2      www.unittest.com/home?query2
                    requests: 4

기본적으로, 나는 알고 싶습니다

당신이 아래의 재현 예를 찾을 수 있습니다. 나는 가능한 한 간결로했습니다.

require("rmongodb")
db  <- "__unittest" 
ns  <- paste(db, "hosts", sep=".")
# CONNCETION OBJECT
con <- mongo.create(db=db)
# ENSURE EMPTY DB
mongo.remove(mongo=con, ns=ns)
q <- list("_id"="abcd")
b <- list("_id"="abcd", name="unittest.com")
mongo.insert(mongo=con, ns=ns, b=b)
q <- list("_id"="abcd")
b <- list("$push"=list(paths=list(path="home")))
mongo.update(mongo=con, ns, criteria=q, objNew=b)
q <- list("_id"="abcd", paths.path="home")
b <- list("$push"=list("paths.$.queries"=list(
    name="query1", url="www.unittest.com/home?query1")))
mongo.update(mongo=con, ns, criteria=q, objNew=b)
b <- list("$push"=list("paths.$.queries"=list(
    name="query2", url="www.unittest.com/home?query2")))
mongo.update(mongo=con, ns, criteria=q, objNew=b)

이 작품은,하지만 (배열 경로의 subdoc 요소에 중첩 된) 두 번째 수준의 배열 쿼리에 대해 명시 적으로 인덱스를 포함한다 :

q <- list("_id"="abcd", paths.path="home", paths.queries.name="query1")
b <- list("$push"=list("paths.$.queries.0.requests"=list(time="2013-02-13")))
> mongo.bson.from.list(b)
    $push : 3    
        paths.$.queries.0.requests : 3   
            time : 2     2013-02-13

mongo.update(mongo=con, ns, criteria=q, objNew=b)
res <- mongo.find.one(mongo=con, ns=ns, query=q)
> res
    _id : 2      abcd
    name : 2     unittest.com
    paths : 4    
        0 : 3    
            path : 2     home
            queries : 4      
                0 : 3    
                    name : 2     query1
                    requests : 4     
                        0 : 3    
                            time : 2     2013-02-13


                    url : 2      www.unittest.com/home?query1

                1 : 3    
                    name : 2     query2
                    url : 2      www.unittest.com/home?query2

지금, 나는 내가 서버가 배열 경로 (경로. $. 쿼리)의 원하는 subdoc 요소를 찾을 수 있기 위하여 그랬던 것처럼 위치 $ 연산자를 명시 적으로 0을 대체하고 싶습니다.

중요한 것은이 "올바른"쿼리 선택기를 지정하는 것입니다으로 AFAIU이 문서는,이 작동합니다 :

나는 (때문에 paths.queries.name = "쿼리 1"부분을) 올바른 중첩 된 요소를 찾을 않는 쿼리 선택기를 지정 생각 :

q <- list("_id"="abcd", paths.path="home", paths.queries.name="query1")

나는 "일반 MongoDB를"구문을 번역 추측 쿼리 선택은 다음과 같이 다소 보인다

{ _id: abcd, paths.path: home, paths.queries.name: query1 }

이는 나에게 유효한 쿼리 선택처럼 보인다. 사실 그것은 원하는 요소 / 문서와 일치 않습니다 :

> !is.null(mongo.find.one(mongo=con, ns=ns, query=q))
[1] TRUE

내 생각은 최상위 수준에서 작동하는 경우, 왜 (오른쪽 중첩 된 구성 요소를 한 쿼리 선택 포인트 등)뿐만 아니라 높은 수준의 작동 안된다고했다?

그러나 서버는 $의 중첩 또는 다중 사용 등을하지 않는 것 같습니다 :

b <- list("$push"=list("paths.$.queries.$.requests"=list(time="2013-02-14")))
> mongo.bson.from.list(b)
    $push : 3    
        paths.$.queries.$.requests : 3   
            time : 2     2013-02-14

> mongo.update(mongo=con, ns, criteria=q, objNew=b)
[1] FALSE

나는 R 구문 권리를하지 않은 경우는 MongoDB를이 지원하지 않기 때문에 작동하지 않거나 있는지 확실하지 않습니다.

해결법

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

    1.위치 연산자는 단지 하나의 레벨에만 깊은 제 매칭 소자를 지원한다.

    위치 연산자는 단지 하나의 레벨에만 깊은 제 매칭 소자를 지원한다.

    당신이 원하는 행동의 종류에 대한 JIRA의 추적 가능한이 있습니다 : https://jira.mongodb.org/browse/SERVER-831

    더 이상의 경기 수 있을지 확실하지 오전하지만 난 그것이 작업에 필요한 방법의 역학에 의한 것으로 판단된다.

  2. ==============================

    2.경우 당신은 MongoDB의 쉘에서 쿼리를 실행할 수 있습니다 할 수 있습니다 MongoDB의 커서의 foreach는 기능을 활용하여이 제한을 우회 (http://docs.mongodb.org/manual/reference/method/cursor.forEach/)

    경우 당신은 MongoDB의 쉘에서 쿼리를 실행할 수 있습니다 할 수 있습니다 MongoDB의 커서의 foreach는 기능을 활용하여이 제한을 우회 (http://docs.mongodb.org/manual/reference/method/cursor.forEach/)

    여기에 3 개 중첩 배열과 예입니다 :

    var collectionNameCursor = db.collection_name.find({...});
    
    collectionNameCursor.forEach(function(collectionDocument) {
        var firstArray = collectionDocument.firstArray;
        for(var i = 0; i < firstArray.length; i++) {
            var secondArray = firstArray[i].secondArray;
            for(var j = 0; j < secondArray.length; j++) {
                var thirdArray = secondArray[j].thirdArray;
                for(var k = 0; k < thirdArray.length; k++) {
                    //... do some logic here with thirdArray's elements
                    db.collection_name.save(collectionDocument);
                }
            }
        }
    });
    

    참고이 더 후 한 번에 솔루션을 생산 코드입니다하지만 당신은 수정 업 스크립트를 작성해야하는 경우가 그 일을 할 것 것이다.

  3. from https://stackoverflow.com/questions/14855246/multiple-use-of-the-positional-operator-to-update-nested-arrays by cc-by-sa and MIT license