Mongodb keeps wrapping a string value with ObjectId(' ') in the database.
when I make a POST request with my endpoint, I get a 200 response and I see the correct value for my creatorID property that is of type string.
it looks like this:
but in MongoDB it is saved like this:
why is it doing that? and can I turn this option off?
my other Id property (on level 1) is the unique id of the object and it gets automatically generated. Both are of type string.
any help would be appreciated!
It can make its own unique definition automatically, you can turn this feature off.
for more detail
example :
var subSchema = mongoose.Schema({
createId: string;
// subschema content..
}, { _id : false });
or
#Prop({_id:false})
SubSchema: subschemaArray;
Related
I am implementing a HTTP PATCH method in golang and postgresql, I need to read the data from the request and update the data provided into the postgresql.
The method works fine if all the values of the struct is provided, but if only partial data is given to a request, the other fields are becoming empty. Can anyone please help me out to deal this problem.
type StudentDetails struct {
Id int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
Class int `json:"class"`
}
Query which I am using "UPDATE table_name SET name=$2, age=$3, class=$4 WHERE id=$1"
If all the fields given in the request this works fine, but if I need to update only the AGE and the request json would be {"age": 10} or some other field we dont know. Here Age is set to 10 but remaining all fields will become "" or 0 and that will be updated into the database
Anyone has the solution to this problem, how to update the requested field only and not change other fields.
I have approached using a separate query for all fields, but I think its not the proper one. Please give me a solution
Like what #David Hall said in the comments, use pointer to a type in the fields of your struct. See example below:
type ArticleModel struct {
gorm.Model
ID uuid.UUID `gorm:"primaryKey;type:uuid"`
Title *string
Body *string
}
I am using gorm, then when unmarshalling the json from http request you will get nil value if not provided. You need to add nil checkers to skip in the construction of your SQL query. Something like this.
if entity.Title != nil {
model.Title = entity.Title
}
if entity.Body != nil {
model.Body = entity.Body
}
db.Save(&model)
Now the next problem would be how to intentionally empty the field in database (explicitly nulling the value) like UPDATE table SET field = null. Unfortunately I haven't figured it out also.
What I have in mind is checking if empty string and considering it as the setting it to empty value. Although I want to see better options.
i would like to kmow the advantages of using virtuals in mongoose while establishing relationship. Will it result in faster retrival of information from DB
Virtuals are additional fields for a given model. Their values can be set manually or automatically with defined functionality. A common virtual property is the full name of a person, composed of user’s first and last name.
virtual properties don’t get persisted in the database. They only exist logically and are not written to the document’s collection.
Example
Mongoose Schema
The user schema has two properties indicating the user’s first and last name: first and last.
// define user schema
var userSchema = new Schema({
first: String,
last: String
});
// compile our model
var User = mongoose.model('User', userSchema);
// create a document
var mentalist = new User({
first: 'Patrick',
last: 'Jane'
});
Assume we want to get the full name of a mentalist, we can do this manually appending the first to last property:
console.log(mentalist.first + ' ' + mentalist.last); // Patrick Jane
Define a Virtual Property
Actually, there is a better way of getting the full name of a user: virtual fields. With virtuals, you benefit of writing the name concatenation mess only once.
Mongoose splits the definiton of virtual fields into GET and SET methods.
Get Method
The virtuals get method is a function returning a the virtual value. You can do complex processing or just concatenate single document field values.
userSchema.virtual('fullname').get(function() {
return this.first + ' ' + this.last;
});
The code example above just concatenates the first and last property values. With that, the virtual fullname property now will print the same output as above:
console.log(mentalist.fullname); // Patrick Jane
Set Method
setter methods are useful to split strings or do other operations. Define a virtual setter by passing a proper function and execute your desired processing. The example below splits the passed name variable at any whitespace.
userSchema.virtual('fullname').set(function (name) {
var split = name.split(' ');
this.first = split[0];
this.last = split[1];
});
The first part of name is assigned to the first and the second part to the last property. This set method will override the previous model values and assign the ones we pass as fullname property.
var humor = new User({
first: '',
last: ''
});
humor.fullname = 'Kimball Cho';
console.log(humor.first); // Kimball
console.log(humor.last); // Cho
Queries and Field Selection
Virtuals are NOT available for document queries or field selection. Only non-virtual properties work for queries and field selections.
As you see, virtual properties aren’t static model properties. They
are additional model functions returning values based on the default
schema fields.
Given a json string:
POST localhost:8080/person
{
f_name : 'Juan',
l_name : 'Dela Cruz'
}
we would usually return a boolean true value upon success so that apigility would return/render something like this:
200 Ok
{
f_name : 'Juan',
l_name : 'Dela Cruz'
}
How can I also include the id of the newly created entity in the resulting response? It may look something like this:
200 Ok
{
id : 1,
f_name : 'Juan',
l_name : 'Dela Cruz'
}
Any help/lead is highly appreciated.
I am including my own answer here, but I think this is not the best possible way.
I have discovered that you can also return an array from the create (POST) method of the resource with the 'id' field taken from the lastInsertValue property of an db adapter object and added into the array.
$insert['f_name'] = 'Juan';
$insert['l_name'] = 'Dela Cruz';
$table = new TableGateway('person', $adapter);
$table->insert($insert);
$insert['id'] = $table->lastInsertValue;
return $insert;
I hope there are still other ways to do this.
Apigility does indeed return the object you send. If you want to get a different result you can construct it yourself and return it as
javiniar.leonard also pointed out.
Important is that you do not try to json_encode it but let Apigility handle that.
I use the API to send items created in an app with a local id, and return the local id and web_id to allow for synchronization on multiple devices.
I want to retrieve the last inserted _id, using mongoose as MongoDB wrapper for node.js. I've found the following tutorial, but I can't change any node modules because the app runs on a public server:
Getting "Last Inserted ID" (hint - you have to hack Mongoose)
Any other ideas? This what I want to do:
Insert new user
Get user's _id value
Set a new session based on user's id
Redirect to /
Thanks!
I'm using mongoose version 1.2.0 and as soon as I created a new instance of a mongoose model, the _id is already set.
coffee> u = new User()
[object Object]
coffee> u._id
4dd68fc449aaedd177000001
I also verified that after I call u.save() the _id remains the same. I verified via MongoHub that this is indeed the real ID saved into MongoDB.
If you explicitly declare
_id: Schema.ObjectId
for your model, then the ObjectId will not be available after new or save.
This is probably a bug.
If you're looking to get the last inserted _id of a sub object, then create the object, and add it to the item. Here's an example in NowJS using MongoDB and Mongoose (to add some schema sugar) which then converts the result to JSON to send back to the client:
var nowRoomID = this.now.room;
var Conversation = mongoose.model('Conversation');
Conversation.findById(convID, function(error, conversation) {
var Blip = mongoose.model('Blip');
var createdBlip = new Blip();
createdBlip.author= nowUserName;
createdBlip.authorid = parsed.authorid;
createdBlip.body = revisedText;
createdBlip.created_at = new Date();
createdBlip.modified_at = new Date();
conversation.blips.push(createdBlip);
parsed._id = createdBlip._id; //NOTE: ID ACCESSED HERE
message = JSON.stringify(parsed);
conversation.save(function (err) {
if (!err) {
console.log('Success - saved a blip onto a conversation!');
nowjs.getGroup(nowRoomID).now.receiveMessage(nowUserName, message);
}
});
With MongoDB, if you don't explicitly set a document's _id value then the client driver will automatically set it to an ObjectId value. This is different from databases that might generate IDs on the server and need another query to retrieve it, like with SQL Server's scope_identity() or MySQL's last_insert_id().
This allows you to insert data asynchronously because don't need to wait for the server to return an _id value before you continue.
So, as shown is Peter's answer, the _id is available before the document is saved to the database.
I just get the id from the document passed to the callback, since save returns the saved document.
Check below url
http://mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
you will find following code in given url
var document = {name:"David", title:"About MongoDB"};
collection.insert(document, {w: 1}, function(err, records){
console.log("Record added as "+records[0]._id);
});
I have not clearly issue during query using two criterials like Id and Other. I use a Repository storing some data like id,iso,value. I have created an index("_id","Iso") to performs queries but queries are only returning my cursor if i use only one criterial like _id, but is returning nothing if a use two (_id, Iso) (commented code).
Are the index affecting the response or the query method are failing?
use :v1.6.5 and C# official.
Sample.
//Getting Data
public List<BsonObject> Get_object(string ID, string Iso)
{
using (var helper = BsonHelper.Create())
{
//helper.Db.Repository.EnsureIndex("_Id","Iso");
var query = Query.EQ("_Id", ID);
//if (!String.IsNullOrEmpty(Iso))
// query = Query.And(query, Query.EQ("Iso", Iso));
var cursor = helper.Db.Repository.FindAs<BsonObject>(query);
return cursor.ToList();
}
}
Data:
{
"_id": "2345019",
"Iso": "UK",
"Data": "Some data"
}
After that I have Updated my data using Update.Set() methods. I can see the changed data using MongoView. The new data are correct but the query is always returning the sames olds values. To see these values i use a page that can eventually cached, but if add a timestamp at end are not changing anything, page is always returning the same olds data. Your comments are welcome, thanks.
I do not recall offhand how the C# driver creates indexes, but the shell command for creating an index is like this:
db.things.ensureIndex({j:1});
Notice the '1' which is like saying 'true'.
In your code, you have:
helper.Db.Repository.EnsureIndex("_Id","Iso");
Perhaps it should be:
helper.Db.Repository.EnsureIndex("_Id", 1);
helper.Db.Repository.EnsureIndex("Iso", 1);
It could also be related to the fact that you are creating indexes on "_Id" and the actual id field is called "_id" ... MongoDB is case sensitive.
Have a quick look through the index documentation: http://www.mongodb.org/display/DOCS/Indexes