Использование $ или массива в запросе
Я пытаюсь запросить MongoDB через R-драйвер rmongodb. В строке cmd работает следующий запрос (результат: 204 915):
db.col1.count(
{
$or: [
{'status.time':{$gt: ISODate('2013-09-10 00:00:00')}},
{'editings.time':{$gt: ISODate('2013-09-10 00:00:00')}}
]
} );
Переведя это в R, я попытался:
d<-strptime('2013-09-10', format='%Y-%m-%d')
buf <- mongo.bson.buffer.create()
mongo.bson.buffer.start.array(buf, "$or")
mongo.bson.buffer.start.object(buf, 'status.time')
mongo.bson.buffer.append(buf, "$gt", d)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.start.object(buf, 'editings.time')
mongo.bson.buffer.append(buf, "$gt", d)
mongo.bson.buffer.finish.object(buf)
РЕДАКТИРОВАТЬ: Это то, что запрос печатает в R:
>mongo.bson.from.buffer(buf)
$or : 4
status.time : 3
$gt : 9 79497984
editings.time : 3
$gt : 9 79497984
Выполнение запроса с помощью...
mongo.count(mongo, db1.col1, query=mongo.bson.from.buffer(buf))
... дает мне "-1". Я попробовал несколько вариантов BSON, все с тем же результатом. Однако использование только одного из условий (без $ или массива) работает. Кто-нибудь видит мою ошибку?
Кстати: я знаю о потоке rmongodb: используя $ или в запросе, однако предлагаемый ответ на использование альтернативного драйвера RMongo не удовлетворяет другим требованиям моего кода.
2 ответа
Ваш способ создания массива Монго Бсон неверен. Вам не хватает частей
mongo.bson.buffer.start.object(buf, "0")
...
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.start.object(buf, "1")
...
mongo.bson.buffer.finish.object(buf)
Для рабочего примера, пожалуйста, проверьте последний комментарий: https://github.com/mongosoup/rmongodb/issues/17
Я надеюсь, что это работает на данный момент. Я работаю над более простым решением!
Чтобы избежать необходимости составлять последовательность операторов mongo.bson.buffer, я написал пакет ( rmongodbHelper), который преобразует JSON или list() в объект BSON, который затем можно использовать с rmongodb.
Сначала давайте настроим среду:
library(rmongodb)
# install rmongodbHelper package from GitHub
library(devtools)
devtools::install_github("joyofdata/rmongodbHelper")
library(rmongodbHelper)
# the MongoDB instance
ns <- "dbx.collx"
M <- mongo.create()
mongo.is.connected(M)
mongo.remove(M, ns, json_to_bson("{}"))
# inserting a number of dummy objects
# JSON keys currently are expected to be wrapped in double quotes!
objs <- c(
'{"_id":"__int(0)", "dates":{}}',
'{"_id":"__int(1)", "dates":{"a":"__time(2013-01-01)", "b":"__time(2013-01-01)"}}',
'{"_id":"__int(2)", "dates":{"a":"__time(2013-01-01)", "b":"__time(2014-01-01)"}}',
'{"_id":"__int(3)", "dates":{"a":"__time(2014-01-01)", "b":"__time(2013-01-01)"}}',
'{"_id":"__int(4)", "dates":{"a":"__time(2014-01-01)", "b":"__time(2014-01-01)"}}'
)
for(obj in objs) {
mongo.insert(M, ns, json_to_bson(obj))
}
Давайте посмотрим через оболочку MongoDB, были ли они успешно вставлены:
> use dbx
switched to db dbx
> db.collx.find().pretty()
{ "_id" : 0, "dates" : { } }
{
"_id" : 1,
"dates" : {
"a" : ISODate("2013-01-01T00:00:00Z"),
"b" : ISODate("2013-01-01T00:00:00Z")
}
}
[...]
{
"_id" : 4,
"dates" : {
"a" : ISODate("2014-01-01T00:00:00Z"),
"b" : ISODate("2014-01-01T00:00:00Z")
}
}
Теперь давайте поищем документы с запросом:
# searching for those objects
# JSON keys currently are expected to be wrapped in double quotes!
json_qry <-
'{
"$or": [
{"dates.a":{"$gt": "__time(2013-06-10)"}},
{"dates.b":{"$gt": "__time(2013-06-10)"}}
]
}'
cur <- mongo.find(M, "dbx.collx", json_to_bson(json_qry))
while(mongo.cursor.next(cur)) {
print(mongo.cursor.value(cur))
}
И вот что мы получаем в итоге:
_id : 16 2
dates : 3
a : 9 -211265536
b : 9 1259963392
_id : 16 3
dates : 3
a : 9 1259963392
b : 9 -211265536
_id : 16 4
dates : 3
a : 9 1259963392
b : 9 1259963392
- ключи - также операторы типа $ или - должны быть заключены в двойные кавычки.
"x":3
приведет к тому, что 3 будут брошены как двойные"x":"__int(3)"
приведет к тому, что 3 будет приведено к целому числу