Wielokrotne użycie operatora pozycyjnego `$` do aktualizacji zagnieżdżonych tablic

To pytanie jest ściśle związane zten i rozważę porady udzielone w odniesieniu do projektowania schematu w kontekście NoSQL, ale jestem ciekawy, aby to zrozumieć:

Rzeczywiste pytania

Załóżmy, że masz następujący dokument:

    _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

Zasadniczo chciałbym to wiedzieć

jeśli możliwe jest użycie pozycji MongoDB$ operator (Detale) wielokrotnie lub inaczej, w scenariuszach aktualizacji, które obejmują struktury tablic / dokumentów z „stopniem zagnieżdżenia” większym niż 1:

{ <update operator>: { "paths.$.queries.$.requests" : value } } (nie działa)

zamiast „tylko” być w stanie korzystać$ pewnego razu dla tablicy najwyższego poziomu i przy użyciu jawnych indeksów dla tablic na „wyższych poziomach”:

{ <update operator>: { "paths.$.queries.0.requests" : value } }) (Prace)

jeśli to możliwe, jak będzie wyglądać odpowiednia składnia R.

Poniżej znajdziesz powtarzalny przykład. Starałem się być jak najbardziej zwięzły.

Przykład koduPołączenie z bazą danych
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)
Przykładowy dokument
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)
Aktualizacja zagnieżdżonych tablic z jawnym indeksem pozycji (działa)

To działa, ale wymagawyraźny indeks dla tablicy drugiego poziomuqueries (zagnieżdżony w elemencie subdoc tablicypaths):

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
Aktualizacja zagnieżdżonych tablic z pozycjonowaniem$ indeksy (nie działa)

Teraz chciałbym zastąpić wyraźne0 z pozycją$ operator tak jak ja, aby serwer znalazł żądany element subdoc tablicypaths (paths.$.queries).

AFAIUdokumentacja, powinno to działać, ponieważ najważniejsze jest określenie „poprawnego” selektora zapytań:

Operator pozycyjny $, gdy jest używany z metodą update () i działa jako symbol zastępczy dla pierwszego dopasowania selektora zapytania aktualizacji:

Myślę, że wybrałem selektor zapytania, któryrobi znajdź właściwy element zagnieżdżony (z powodupaths.queries.name="query1" część):

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

Sądzę, że przetłumaczony na „zwykłą składnię MongoDB”, selektor zapytań wygląda trochę tak

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

który wydaje mi się prawidłowym selektorem zapytań. W rzeczywistości pasuje do żądanego elementu / doc:

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

Myślałem, że jeśli działa na najwyższym poziomie, to dlaczego nie miałoby działać również na wyższych poziomach (tak długo, jak selektor zapytań wskazuje odpowiednie zagnieżdżone komponenty)?

Jednak serwer nie lubi zagnieżdżonego lub wielokrotnego użycia$:

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

Nie jestem pewien, czy to nie działa, ponieważ MongoDB nie obsługuje tego lub jeśli nie otrzymałem poprawnej składni R.

questionAnswers(2)

yourAnswerToTheQuestion