Insert field name with dot in mongo document - mongodb

A Meteor server code tries to insert an object into a Mongo collection. The value of one of the property is a string which contains a dot i.e. ".".
Meteor terminal is complaining :-
Error: key Food 1.1 and drinks must not contain '.'
What does this mean and how to fix it?
let obj = {
food: group,
rest: rule,
item: item[0],
key: i
};
FoodCol.insert(obj);
edit
The suggested answer by Kishor for replacing the "." with "\uff0E" will produce a space after the dot which is not what a user expects.

From this link, How to use dot in field name?
You can replace dot symbols of your field name to Unicode equivalent
"\uff0E":
Update: As Fred suggested, please use "\u002E" for "."

We solved this issue by encoding (Base64) the key before insertion and decode after taking out from the db. Since we consume the document as it is and query fields are different and their keys are not encoded.
But if u want to make query using this key or the key should be readable to the user, this solution will be not be suitable.

Related

firestore document snapshot get() does not work with dotted string notation of field-names containing hyphen

I've a simple document called 'agents' under a collection named 'mycoll' with data set something like below:
{
'metadata': {
'agent-ids': ['fdfd', 'asdfasdf', 'rerere'],
'agent_ids': ['foo1', 'booo']
}
I got the document snapshot:
snapshot = firestore.client().document('mycoll/agents').get()
If I try to access 'agent-ids' field name using get() method on this snapshot:
agent-list-with-hypens = snapshot.get('metadata.agent-ids')
ValueError: Path metadata.agent-ids not consumed, residue: -ids
However, If I try to access 'agent_ids' using get() method, that works just fine:
print(snapshot.get('metadata.agent_ids'))
['foo1', 'booo']
My question is what is causing this different behavior for field-names with an '-' and why? Any documentation which explains about this? I understand that snapshot.get() accpets a FieldPath argument instead of plain string but existing API documentation does not warn that field-names with an '-' are not allowed in field-path name strings delimited by '.'
In fact, snapshot.get(firestore.client().field_path('metadata', 'agent-ids')) works just fine.
Based on the documentation, here are the constraints on field paths:
Must separate field names with a single period (.)
Must enclose each field name in backticks unless the field name meets the following requirements:
The field name contains only the characters a-z, A-Z, 0-9, and underscore (_)
The field name does not start with 0-9
So a field name/path containing dash will raise ValueError. The above constraints also explain why snapshot.get(firestore.client().field_path('metadata', 'agent-ids')) works just fine is because the field name is enclosed in backticks.

Data factory lookup (dot) in the item() name

I am having lookup wherein salesforce query is there. I am using elements (item()) in subsequent activities. Till now i had item().name or item().email but now i have item().NVMStatsSF__Related_Lead__r.FirstName which has (dot) in the field name.
How should i parse it through body tag so that it reads it correctly?
So I have the following data in item()
{
"NVMStatsSF__Related_Lead__c": "00QE000egrtgrAK",
"NVMStatsSF__Agent__r.Name": "ABC",
"NVMStatsSF__Related_Lead__r.Email": "geggegg#gmail.com",
"NVMStatsSF__Related_Lead__r.FirstName": "ABC",
"NVMStatsSF__Related_Lead__r.OwnerId": "0025434535IIAW"
}
now when i use item().NVMStatsSF__Agent__r.Name it will not parse because of (dot) after NVMStatsSF__Agent__r. And it is giving me the following error.
'item().NVMStatsSF__Related_Lead__r.Email' cannot be evaluated because property 'NVMStatsSF__Related_Lead__r' doesn't exist, available properties are 'NVMStatsSF__Related_Lead__c, NVMStatsSF__Agent__r.Name, NVMStatsSF__Related_Lead__r.Email, NVMStatsSF__Related_Lead__r.FirstName, NVMStatsSF__Related_Lead__r.OwnerId'.",
"failureType": "UserError",
"target": "WebActivityToAddPerson"
this is because ADF uses '.' for object reading.
Could you find a way to rename the field name which contains '.'?
Seems like you need a built-in function to get the value of an object according to the key. Like getValue(item(), 'key.nestkey'). But unfortunately, seems there isn't such a function. You may need handle your key first.
Finally, it worked. I was being silly.
Instead of taking the value from the child table with the help of (dot) operator I just used subquery. Silly see.
And it worked.

Couchbase startkey as literal value

I am using couchbase to save objects.
The key of a document looks like this
"xxxx_someRandomValue"
For example, i can have this keys
aaaa_1
aaaa_2
aaab_1
aaab_2
I am making a view, which should return me all the documents of which key starts with literal "aaaa".
But, if i specify startKey="aaaa", it also finds for me "aaab", because it is comparing it in unicode values.
Can i force the view to return me just the documents of which key start with literal "aaaa_" ?
Found the solution:
To work as a prefix, this should work
startkey="aaaa"&endkey="aaaa\u02ad"
documentation
Have you tried with an endkey value in addition to your startkey, something like
&startkey="aaaa"&endkey="aaaa\uefff"
You can find more information about sorting here:
http://blog.couchbase.com/understanding-letter-ordering-view-queries
try this one
startkey=aaaa&endkey=aaab
The API startKey(final String KEY) returns all the jsons whose keys (document name) are bigger or equal than the unicode value of KEY.
The API endKey(final String KEY) returns all the jsons whose keys (document name) are smaller than the unicode value of KEY.
So in your case startkey="aaaa"&endkey="aaab" (as suggested by avsej) should give you the desired result.
So the common sense says the API endKey is about compare the end of the key but it's false.

Casbah: How to Update and Embedded Object When Field Names Have Spaces?

Supposing I had the following document in a database:
{"_id":"test", "with space":{"a name":1}}
How can I write a $set query in Casbah to update "with space"."a name" to 2?
I was thinking something along the lines of:
collection.update(MongoDBObject("_id" -> "test"), "'with space'.'a name'" $set 2)
But what if my field names were unknown and I had to compose them at runtime? Is there any way to "escape" them in a safe way? (For example, what if any of them contains single quotes, etc.)
How about not putting spaces in your field names. Seriously.
Ok, if you really must, it should work fine without escaping...
collection.update(MongoDBObject("_id" -> "test"), $set ("with space.a name" -> 2))
There isn't any explicit escaping required for MongoDB; you can just pass a variable name, eg:
val key = MongoDBObject(name + '.' + embeddedname -> "somevalue")
or
val key = MongoDBObject("with space.a name" -> "somevalue")
While MongoDB does allow you to use any valid UTF-8 character in key names aside from '.' and a leading '$', you would generally be best sticking to alphanumeric key names plus underscore.
If you are concerned about safety of user-provided input, see How does MongoDB address SQL or Query injection?

Mongoid, find object by searching by part of the Id?

I want to be able to search for my objects by searching for the last 4 characters of the id. How can I do that?
Book.where(_id: params[:q])
Where the param would be something like a3f4, and in this case the actual id for the object that I want to be found would be:
bc313c1f5053b66121a8a3f4
Notice the last for characters are what we searched for. How can I search for just "part" of my objects id? instead of having my user search manually by typing in the entire id?
I found in MongoDB's help docs, that I can provide a regex:
db.x.find({someId : {$regex : "123\\[456\\]"}}) // use "\\" to escape
Is there a way for me to search using the regular mongo ruby driver and not using Mongoid?
Usually, in Mongoid you can search with a regexp like you normally would with a string in your call to where() ie:
Book.where(:title => /^Alice/) # returns all books with titles starting with 'Alice'
However this doesn't work in your case, because the _id field is not stored as a string, but as an ObjectID. However, you could add (and index) a field on your models which could provide this functionality for you, which you can populate in an after_create callback.
<shameless_plug>
Alternatively, if you're just looking for a shorter solution to the default Mongoid IDs, I could suggest something like mongoid_token which makes it pretty easy to add shorter tokens/ids to your Mongoid documents.
</shameless_plug>