I have a question about MongoDB id for grails. I used String id in domain class, it would create string id in domain class which is fine. But when I insert entries in mongodb mannually(run db.Things.insert()), it would create an ObjectId(which is not String) for the new entry, I wonder how we could resolve this issues.
thanks!
Refrence from: Mongo Collections - Reference Documentation
By default in GORM entities are supplied with an integer-based
identifier. So for example the following entity: class Person {} Has
a property called id of type java.lang.Long. In this case GORM for
Mongo will generate a sequence based identifier using the technique
described in the Mongo documentation on Atomic operations.
However, sequence based integer identifiers are not ideal for
environments that require sharding (one of the nicer features of
Mongo). Hence it is generally advised to use either String based ids:
class Person {
String id } Or a native BSON ObjectId:
import org.bson.types.ObjectId class Person {
ObjectId id }
BSON ObjectId instances are generated in a similar fashion to UUIDs.
So you should replace your domain class's id using org.bson.types.ObjectId
I figured out that I could create a new ObjectId first then when I insert it into the mongoDb, I pass the ObjectId.str for the "_id" property, then problem resolved, both mongo db level and grails level will have String type for id field.
Code snippet is as following for mongo javascript script:
conn = new Mongo();
db = conn.getDB("dbName");
db.user.find().forEach( function(userDoc) {
// Create a new object Id
objectId = new ObjectId();
db.userRole.insert({
_id: objectId.str, // Before we insert, convert it as a String
role: "51437d742cd1d9e80a3f0644",
user: userDoc._id
});
});
Related
I have a case where I need to change the default referencing of primary key name id with _id for all the models in a given project I am working.
There is an express.js + mongoose setup which is in production. The data present in the database is directly referred by our users using mobile application. And the code of mobile application is very much aware of reading _id as the key in all the documents it receives in JSON.
Since sails uses waterline which has default key name as id and it maps to _id for mongodb, the underlying database will be used as it is, however on the middleware we are always reading it as id.
I have searched through the web and tried to have default id name as _id in the config/models.js, but the schema creation outputs an error stating _id, _id is used twice.
Production database, Waterline ... I recommend against actually changing your primary keys. Heck, I'd recommend against that kind of monkey-wrench if you were using a much more mature ORM.
Instead, I say, transform the key names in your action. e.g. in an action2, where you just return template variables at the end of a function:
r = await Model.findOne(where);
return {
_id: r.id, // <---- this bit <----
etc: r.etc
}
And then make a JSON structure as your view template.
I have an application which uses a Mongo database. I often use the ID of the records which are ObjectIds/strings like 507f1f77bcf86cd799439011.
My issue is when I run my site i development mode, the Sails application is using in-memory store and uses numbers/interger as the objectId. That screws with my application.
I want Sails to always store the id as an string.
Whats the best way of dealing with this issue ?
In your config/models.js file, edit the default id attribute to have the
appropriate type and columnName for MongoDB's primary keys:
attributes: {
id: { type: 'string', columnName: '_id' },
//…
}
for more please follow the sails mongo docs:
https:`//sailsjs.com/documentation/tutorials/using-mongo-db
Looking for options to use the graphlookup pipeline where the from field is the string value of the Object Id and the to field is Object Id.
You can make your 'from field' to be stored as ObjectId by adding following annotation:
#Field(targetType = FieldType.OBJECT_ID)
Still not possible. and there is no field casting available for $graphlookup
My document has some EmbeddedDocumentList and each of EmbeddedDocument should have autogenerated ObjectId(like _id) field because I will write query to get single EmbeddedDocument with this _id field.
How to reach that?
Basically you can do it with following code
from mongoengine import *
from bson.objectid import ObjectId
class MyEmbeddedDocument(EmbeddedDocument):
oid = ObjectIdField(required=True, default=ObjectId,
unique=True, primary_key=True)
...
class MyDocument(Document):
embedded_list = EmbeddedDocumentListField(MyEmbeddedDocument)
...
Let explain more,
According to documentation you can add ObjectIdField to your models however it is not required and primary_key then you should set this attribute as True. Also, it do not generate ObjectId for each of it then import and set default it as ObjectId.
Last step is little bit tricky. If it is required explain,
bson.objectid.ObjectId is class that generate new objectids.
Moreover documentation say that default value can be callable than that explain clearly how it is work.
Also name of _id for embeddeddocument is not best naming practise beacuse you will write query for embeddeddocument with duble underscore and '_id' name have one more underscore as following code
MyDocument.objects.get(notice___id)
Then mongoengine throws exception beacuse of '_id' name have one more underscore. Thus you should give name as 'oid' as a short version of objectId or renname 'id' directly or what you want.
I have a collection:
{
_id - ObjectId
name - string
location - string
..
parentId - ObjectId //link to parent object
}
I have a filter query and it works nice even with int values (in C#):
var q = Query.Matches(column, new BsonRegularExpression(string.Format("/^{0}/i", name)));
What should I do in order to search by the name of parent object? Of cause, using LINQ, there is no problem, but is it possible to conduct searching on the server side?
There are no joins in MongoDB, but you basically have two options:
Solution 1:
Query by the name and fetch the result (the parents)
For every document fetched, query again and fetch all documents where the _id and the parentId match (the children)
Solution 2:
Additionally to the parentId, also save the name of the parent's name with each document and query directly for parentName
There is not way to search by referenced object fields in mongodb. And in general monogdb is not relational database, so in my opinion it should not support any relations at all.
There is good known approach it is create additional field and store (denormalize) information on what you want search.
So, change your schema as follow to search on parent object name:
{
_id - ObjectId
name - string
location - string
..
parentId - ObjectId //link to parent object,
parentName
}
The main idea you should understand: mongodb is not realtional, no joins here, no relations.