Querying RMongo with ObjectId - r

Is there a way to query in RMongo with an ObjectId?
Something like:
results <- dbGetQuery(mongo, "users", "{'_id': 'ObjectId('5158ce108b481836aee879f8')'}")
Perhaps by importing a bson library?

RMongo's dbGetQuery() function is expecting MongoDB Extended JSON syntax for the provided query string.
The MongoDB Extended JSON equivalent of ObjectId("<id>") is { "$oid": "<id>" }:
results <- dbGetQuery(mongo, "users", "{'_id': { '$oid': '5158ce108b481836aee879f8' }}")

Try the new mongolite package:
library(mongolite)
m <- mongo("users")
m$find('{"_id":{"$oid":"5158ce108b481836aee879f8"}}')

mongo.oid.from.string {rmongodb}
Create a mongo.oid object ftom a string
Package: rmongodb
Version: 1.5.3
Description
Create from a 24-character hex string a mongo.oid object representing a MongoDB Object ID.
Usage
mongo.oid.from.string(hexstr)
Arguments
hexstr
(string) 24 hex characters representing the OID.
Note that although an error is thrown if the length is not 24, no error is thrown if the characters are not hex digits; you'll get zero bits for the invalid digits.
Details
See http://www.mongodb.org/display/DOCS/Object+IDs
Values

Related

r json mongodb query $in operator syntax error due to double quotes?

I'm building a json query to pass to a mongodb database in R.
In one scenario, I have a vector of dates and I want to query the database to return all records which have a date in the relevant field that matches a date in my vector of dates.
The second scenario is the same as the first, but this time I have a vector of character strings (IDs) and need to return all the records with matching IDs.
I understood the correct way to do this in a json query is to use the $in operator, and then put my vector in an array.
However, when I pass the query to my mongodb database, the exportLogId returns NULL. I'm quite sure that the problem is something to do with how I am representing the $in operator in the final query, since I have very similarly structured queries without the $in operator and they are all working. If I look for just one of my target dates or character strings, I get the desired result.
I followed the mongodb manual here to construct my query, and the only issue I can see is that the $in operator in the output of jsonlite::toJSON() is enclosed in double quotes; whereas I think it might need to be in single quotes (or no quotes at all, but I don't know how to write the syntax for that).
I'm creating my query in two steps:
Create the query as a series of nested lists
Convert the list object to json with jsonlite::toJSON()
Here is my code:
# Load libraries:
library(jsonlite)
# Create list of example dates to query in mongodb format:
sampledates <- c("2022-08-11T00:00:00.000Z",
"2022-08-15T00:00:00.000Z",
"2022-08-16T00:00:00.000Z",
"2022-08-17T00:00:00.000Z",
"2022-08-19T00:00:00.000Z")
# Create query as a list object:
query_list_l <- list(filter =
# Add where clause:
list(where =
# Filter results by list of sample dates:
list(dateSampleTaken = list('$in' = sampledates),
# Define format of column names and values:
useDbColumns = "true",
dontTranslateValues = "true",
jsonReplaceUndefinedWithNull = "true"),
# Define columns to return:
fields = c("id",
"updatedAt",
"person.visualId",
"labName",
"sampleIdentifier",
"dateSampleTaken",
"sequence.hasSequence")))
# Convert list object to JSON:
query_json = jsonlite::toJSON(x = query_list_l,
pretty = TRUE,
auto_unbox = TRUE)
The JSON query now looks like this:
> query_json
{
"filter": {
"where": {
"dateSampleTaken": {
"$in": ["2022-08-11T00:00:00.000Z", "2022-08-15T00:00:00.000Z", "2022-08-16T00:00:00.000Z", "2022-08-17T00:00:00.000Z", "2022-08-19T00:00:00.000Z"]
},
"useDbColumns": "true",
"dontTranslateValues": "true",
"jsonReplaceUndefinedWithNull": "true"
},
"fields": ["id", "updatedAt", "person.visualId", "labName", "sampleIdentifier", "dateSampleTaken", "sequence.hasSequence"]
}
}
As you can see, $in is now enclosed in double quotes, even though I put it in single quotes when I created the query as a list object. I have tried replacing with sprintf() but that just adds a lot of backslashes to my query. I also tried:
query_fixed <- gsub(pattern = "\\"\\$\\in\\"",
replacement = "\\'$in\\'",
x = query_json)
... but this fails with an error.
I would be very grateful to know if:
The syntax problem that is preventing $in from working is actually the double quotes?
If double quotes is the problem, how do I replace them with single quotes without messing up the JSON format?
UPDATE:
The issue seems to occur when R is passing the query to the database, but I still can't work out exactly why.
If I try the query out in loopback explorer in the database, it works and using the export log ID produced, I can then fetch the results with httr::GET() in R. Example query results are shown below (sorry for the hashes - the main point is you can see the format of the returned values):
[1] "[{\"_id\":\"e59953b6-a106-4b69-9e25-1c54eef5264a\",\"updatedAt\":\"2022-09-12T20:08:39.554Z\",\"dateSampleTaken\":\"2022-08-16T00:00:00.000Z\",\"labName\":\"LNG_REFERENCE_DATA_CATEGORY_LAB_NAME_LAB_A\",\"sampleIdentifier\":\"LS0044-SCV2-PCR\",\"sequence\":{\"hasSequence\":false},\"person\":{\"visualId\":\"C-2022-0002\"}},{\"_id\":\"af5cd9cc-4813-4194-b60b-7d130bae47bc\",\"updatedAt\":\"2022-09-12T20:11:07.467Z\",\"dateSampleTaken\":\"2022-08-17T00:00:00.000Z\",\"labName\":\"LNG_REFERENCE_DATA_CATEGORY_LAB_NAME_LAB_A\",\"sampleIdentifier\":\"LS0061-SCV2-PCR\",\"sequence\":{\"hasSequence\":false},\"person\":{\"visualId\":\"C-2022-0003\"}},{\"_id\":\"b5930079-8d57-43a8-85c0-c95f7e0338d9\",\"updatedAt\":\"2022-09-12T20:13:54.378Z\",\"dateSampleTaken\":\"2022-08-16T00:00:00.000Z\",\"labName\":\"LNG_REFERENCE_DATA_CATEGORY_LAB_NAME_LAB_A\",\"sampleIdentifier\":\"LS0043-SCV2-PCR\",\"sequence\":{\"hasSequence\":false},\"person\":{\"visualId\":\"C-2022-0004\"}}]"

mongolite: how to perform a LIKE query?

I want to perform a partial match query on a MongoDB in R. I've tried to specify a query that matches the MongoDB query format like so:
library(mongolite)
foo <- mongo(url = "myConnectionString")
bar <- foo$find(
query = '{"_id": /idContainsThis/}',
fields = '{}'
)
But when I try this, I get the following error:
Error: Invalid JSON object: {"_id": /idContainsThis/}
I can't use this solution because if I put quotes round the term, the / is taken as a string literal, not the wildcard I need.
Does anyone know how to make this work with mongolite?
You'll have to use the regex function like this
query = '{"_id": { "$regex" : "idContainsThis", "$options" : "i" }}'
The "$options" : "i" is in case you want it to be case insensitive.
However I am not sure if this will work on an _id

mongolite filtering with dynamic array in r shiny

I have a select input with multiple options and my Mongo query
Here is the array if elements:
c<- c("elen","shallen")
query1 <- paste0('{"client": {"$in"["',c,'"]}')
#sales info is the data base
salesinfo$find(fields = '{"store":true,"_id":false}',query = query1)
Error: Invalid JSON object: {"client": [ elen ]}{"client": [ shallen ]}
this isn't working please help me please remember that it is a dynamic array and the values will change
After extensive research i found a way to solve the issue and i hope my solution will help out guys like me.
q1=paste(shQuote(c, type="cmd"), collapse=", ")
this step is to ensure you print out the array as a string and then use the query
query =paste0('{"store":{"$in":[',q1,']}}')
and the next step would be incorporating it to the query
salesinfo$find(fields = '{"store":true,"_id":false}',query = query)

How to Update A boolean value in mongo using mongoite in R

I am unable to update a bool value in mongo using mongolite. I have a bool value (FALSE) in r and I am trying to update a field in mongo which is currently having value true(mongo bool). But After making update command using mongolite, stored bool value true in mongo changed to string value FALSE(R bool type).
mongolite doesn't automatically update r booleans as mongo booleans.
this throws an Error: Invalid JSON object for me:
m$update('{"name":"foo", "$set":{"boolean":FALSE}}')
this inserts FALSE as string:
m$update('{"name":"foo", "$set":{"boolean":"FALSE"}}')
this inserts false as boolean:
m$update('{"name":"foo", "$set":{"boolean":false}}')
if you're making the update query programmatically you can do something like this:
```
my_boolean <- FALSE
my_updateQuery <- paste0('{"$set":{"boolean":',tolower(paste0(my_boolean)),'}}')
m$update('{"name":"foo", my_updateQuery)
```

Error in eval(expr, envir, enclos) when using rmongodbHelper

I'm working with rmongodb and rmongodbHelper packages and i've built this function.
CUPS_CP_TAR36 <- function(codi,cant){
cups <- vector()
query <- json_to_bson('{"clLst.U_COD_POSTAL": codi, "clLst.TARIFA_ATR": {"$in": "3.0A","3.1A","6.1"]}}')
output <- json_to_bson('{"id":1}')
cursor <- mongo.find(mongo, sips, query, fields=output, limit=cant)
k = 0
while(mongo.cursor.next(cursor)){
k = k + 1
cups[k] <- mongo.bson.value(mongo.cursor.value(cursor), "_id")
}
return(cups)
}
but when I try to use it:
example <- CUPS_CP_TAR36(codi="08036", cant=10)
I get the following error and really dont know why, i'm not used to write my own functions:
Error in eval(expr, envir, enclos) : object 'codi' not found
Thanks!
Try latest rmongodb version from github. bson from json works out of the box. Moreover mongo.bson.to.list works fine for every case, so you dont't need to construct bson from json. I have plans to push new version of the package to CRAN next week.
library(devtools)
install_github("mongosoup/rmongodb")
query <- json_to_bson('{"clLst.U_COD_POSTAL": codi, ...}')
json_to_bson() expects a JSON string. The string you provide is not valid JSON, just as {"key":val} is not valid - while {"key":"val"} or {"key":3.14} are valid.
Of course codi isn't even intended by you to be a string in your case but to be a variable. But as you write the code there is no way for R to know about that.
So you might write:
query <- json_to_bson(sprintf('{"clLst.U_COD_POSTAL": "%s", ...}',codi))
The equivalent expression with your value of codi is then:
query <- json_to_bson('{"clLst.U_COD_POSTAL": "08036", ...}')
The reason why there is an error message involving eval() is b/c I wrote the interpretation of the JSON very, very simple - mind this "package" is merely a workaround and hopefully superfluous very soon.
The JSON is turned into a list()-expression using string-substitution and then eval()ed.
rmongodbHelper / R / json_to_list.R:
json_to_list <- function(json) {
json <- gsub("\n","",json)
json <- gsub("\\{\\}","list()",json)
[...]
json <- gsub("\\$","_$",json)
return(eval(parse(text = json)))
}
Further details: MongoDB – State of the R

Resources