Этот вопрос тесно связан с этим, и я рассмотрю совет, приведенный в отношении дизайна схемы в контексте 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
В принципе, я хотел бы знать
-
если можно использовать оператор MongoDB positional
$
(details) несколько раз или по-другому в обновлении сценарии, которые включают структуры массива/документа с "степенью вложенности" больше 1:{ <update operator>: { "paths.$.queries.$.requests" : value } }
(не работает)вместо "only" сможет использовать
$
один раз для массива верхнего уровня и привязан к использованию явных индексов для массивов на "более высоких уровнях":{ <update operator>: { "paths.$.queries.0.requests" : value } }
) (работает) -
если возможно вообще, как будет выглядеть соответствующий синтаксис R.
Ниже вы найдете воспроизводимый пример. Я старался быть максимально лаконичным.
Пример кода
Соединение с базой данных
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)
Обновление вложенных массивов с явным индексом позиции (работает)
Это работает, но он включает в себя явный индекс для массива второго уровня queries
(вложенный в элемент subdoc массива paths
):
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
Обновление вложенных массивов с позиционными индексами $
(не работает)
Теперь я хотел бы подставить явный 0
оператор positional $
, как и я, чтобы сервер нашел нужный элемент subdoc массива paths
(paths.$.queries
).
AFAIU документация, это должно работать как решающее условие, чтобы указать "правильный" селектор запросов:
Оператор positional $при использовании с методом update() и выступает в качестве заполнителя для первого совпадения селектора запросов обновлений:
Я думаю, что я определил селектор запросов, который делает, чтобы найти правильный вложенный элемент (из-за части paths.queries.name="query1"
):
q <- list("_id"="abcd", paths.path="home", paths.queries.name="query1")
Я предполагаю, что переведен на синтаксис "plain MongoDB", селектор запросов выглядит примерно так:
{ _id: abcd, paths.path: home, paths.queries.name: query1 }
который кажется мне действительным селектором запросов. Фактически он соответствует желаемому элементу /doc:
> !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
Я не уверен, что это не работает, потому что MongoDB не поддерживает это, или если я не получил правильность синтаксиса R.