2

サブドキュメント全体ではなく、サブドキュメントの特定のフィールドを更新する方法を理解するのに問題があります。

サブドキュメントの特定のフィールド値を照会する方法は理解したようですが、照会されたフィールドのみを変更する BSON ドキュメントをどのように構造化する必要があるかについてはわかりません。

「プレーンなMongoDB構文」がR構文にどのように変換されるか、および更新演算子がどのように正確に機能するかを完全には理解していないように感じます。その点でのヒントは大歓迎です。

予選

pkg <- "rmongodb"
lib <- file.path(R.home(), "library")
if (!suppressWarnings(require(pkg, lib.loc=lib, character.only=TRUE))) {
    install.packages(pkg, lib=lib)
    require(pkg, lib.loc=lib, character.only=TRUE)
}

db      <- "__test"
ns.0    <- "user"
ns      <- paste(db, ns.0, sep=".")
con     <- mongo.create(db=db)

空の DB の確保

mongo.remove(mongo=con, ns=ns) 

ドキュメントの挿入

このセクションでは、DB 内のいくつかのサンプル データを確認するだけです。あくまで精神的に飛ばせる補助パートです!! セクション「クエリ」に進み、「実際のクエリ」を参照して、以下の R コードから把握するのが難しいドキュメント構造を理解してください。

ドキュメント 1 の BSON

blist <- NULL
buf <- mongo.bson.buffer.create()
mongo.bson.buffer.append(buf, name="host", 
    value="unittest.com")
mongo.bson.buffer.start.array(buf, "paths")
mongo.bson.buffer.start.object(buf, "1")
mongo.bson.buffer.append(buf, name="path", 
    value="home")
mongo.bson.buffer.append(buf, name="url", 
    value="www.unittest.com/home")
mongo.bson.buffer.start.array(buf, "queries")
mongo.bson.buffer.start.object(buf, "1")
mongo.bson.buffer.append(buf, name="query", 
    value="?somequery")
mongo.bson.buffer.append(buf, name="url", 
    value="www.unittest.com/home?somequery")
mongo.bson.buffer.finish.object(buf) # finish query:1
mongo.bson.buffer.start.object(buf, "2")
mongo.bson.buffer.append(buf, name="query", 
    value="?someotherquery")
mongo.bson.buffer.append(buf, name="url", 
    value="www.unittest.com/home?someotherquery")
mongo.bson.buffer.finish.object(buf) # finish query:2
mongo.bson.buffer.finish.object(buf) # finish queries
mongo.bson.buffer.finish.object(buf) # finish path:1
mongo.bson.buffer.start.object(buf, "2")
mongo.bson.buffer.append(buf, name="path", 
    value="somepage")
mongo.bson.buffer.append(buf, name="url", 
    value="www.unittest.com/somepage")
mongo.bson.buffer.start.array(buf, "queries")
mongo.bson.buffer.start.object(buf, "1")
mongo.bson.buffer.append(buf, name="query", 
    value="?somequery")
mongo.bson.buffer.append(buf, name="url", 
    value="www.unittest.com/somepage?somequery")
mongo.bson.buffer.finish.object(buf) # finish query:1
mongo.bson.buffer.start.object(buf, "2")
mongo.bson.buffer.append(buf, name="query", 
    value="?someotherquery")
mongo.bson.buffer.append(buf, name="url", 
    value="www.unittest.com/somepage?someotherquery")
mongo.bson.buffer.finish.object(buf) # finish query:2
mongo.bson.buffer.finish.object(buf) # finish queries
mongo.bson.buffer.finish.object(buf) # finish path:2
mongo.bson.buffer.finish.object(buf) # finish paths
mongo.bson.buffer.finish.object(buf) # finish buf

b <- mongo.bson.from.buffer(buf)
blist <- c(blist, list(b))

ドキュメント 2 の BSON

編集 2012-01-23

質問を理解しやすくするために、このセクションを削除しました。

実際の挿入

sapply(blist, function(ii) {
    mongo.insert(mongo=con, ns=ns, b=ii)
})

クエリ

クエリの BSON

buf <- mongo.bson.buffer.create()
mongo.bson.buffer.start.object(buf, "paths")
mongo.bson.buffer.start.object(buf, "$elemMatch")
mongo.bson.buffer.start.object(buf, "queries")
mongo.bson.buffer.start.object(buf, "$elemMatch")
mongo.bson.buffer.append(buf, name="query", value="?somequery")
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
query <- mongo.bson.from.buffer(buf)
> query
    paths : 3    
        $elemMatch : 3   
            queries : 3      
                $elemMatch : 3   
                    query : 2    ?somequery

実際のクエリ

> mongo.find.one(mongo=con, ns=ns, query=query)
    _id : 7      50feff31ba54a032514b6181
    host : 2     unittest.com
    paths : 4    
        1 : 3    
            path : 2     home
            url : 2      www.unittest.com/home
            queries : 4      
                1 : 3    
                    query : 2    ?somequery
                    url : 2      www.unittest.com/home?somequery

                2 : 3    
                    query : 2    ?someotherquery
                    url : 2      www.unittest.com/home?someotherquery



        2 : 3    
            path : 2     somepage
            url : 2      www.unittest.com/somepage
            queries : 4      
                1 : 3    
                    query : 2    ?somequery
                    url : 2      www.unittest.com/somepage?somequery

                2 : 3    
                    query : 2    ?someotherquery
                    url : 2      www.unittest.com/somepage?someotherquery

更新中

更新用 BSON

queryサブドキュメントのフィールドの値を設定したいと思いqueryます。私はMongoDBマニュアルを見て、次のようなことを試しました(配列が関係しているため、 $setand演算子を使用しています):$

buf <- mongo.bson.buffer.create()
mongo.bson.buffer.start.object(buf, "$set")
mongo.bson.buffer.start.object(buf, "paths")
mongo.bson.buffer.start.object(buf, "$")
mongo.bson.buffer.start.object(buf, "queries")
mongo.bson.buffer.start.object(buf, "$")
mongo.bson.buffer.append(
    buf, 
    name="name", 
    value="abcd"
)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
bnew <- mongo.bson.from.buffer(buf)

> bnew
    $set : 3     
        paths : 3    
            $ : 3    
                queries : 3      
                    $ : 3    
                        name : 2     abcd

実際の更新

どうやら、これは良い選択ではありませんでした;-)

res <- mongo.update(mongo=con, ns=ns, criteria=query, 
    objNew=bnew, flags=mongo.update.multi)

> res
[1] FALSE

2 : http://docs.mongodb.org/manual/applications/update/#update-operators zU

4

1 に答える 1