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 pytaniaZałóż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ą danychrequire("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 dokumentq <- 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.