Mongo: find by ObjectId is not defined in meteor? - javascript

I am using existing Mongodb in meteor project. The existing mongo id represented by ObjectId(). When I try to find by _id, Meteor says ObjectId is not defined
JS:
Names = new Mongo.Collection('name_list', {idGeneration: 'MONGO'});
Names.find({"_id" : ObjectId("5539d9dcf046be5b2302aefc")}) //ReferenceError: ObjectId is not defined
The above JavaScript code is run in server.

You have to use new Mongo.ObjectID("5539d9dcf046be5b2302aefc"). See the meteor docs for some caveats.
If you want to save having to type new and Mongo. each time, you can define a function:
function ObjectId(hexString) { return new Mongo.ObjectID(hexString); };
and then the code you wrote will work.

You just need to require the ObjectId function from your mongo.
ObjectId = require('mongodb').ObjectID;
Then you can use it like that:
ObjectId("5539d9dcf046be5b2302aefc")

If you are using mongojs:
db.mycollection.findOne({
_id: mongojs.ObjectId('your object id')
}, function(err, doc) {
//do your stuff here.
})

Related

AngularFire collectionGroup always throws error not a valid function

I'm using Ionic 4 and have just integrated with AngularFire. Collections and documents work well, however I cannot get the collectionGroup function to work - it always gives an error that the function does not exist.
Relevant code is :
this.user = this.firestore.collection('profile').doc(tok.uid);
async StoreRecipe(recipe_name,meal) {
var ua = await this.read_foods_meal(meal+1)
console.log(meal);
ua.subscribe( foods => { console.log(foods);
foods.forEach(food => { this.user.collection('recipe').doc(recipe_name).collection('foods').add(food);} )
});
}
async read_recipes() {
var ua = await this.user.collectionGroup('recipe');
return(ua);
}
I have updated all modules with 'Fire' in the name to the latest version :
#angular/fire
#ionic-native/firebase-x
angularfire
firebase
firebase-admin
But the error still appears. Also, If I try to query the recipe collection using the .collection() function it just returns a null result .. even though there are documents under the 'recipe'collection
You user object is an instance of the firebase.firestore.DocumentReference class, and it does not have a collectionGroup method. Check the documetation here.
If you want to run a query across various collections, these should have the same name, and you can use the firebase.firestore().collectionGroup() method. You can find how to configure it in this link.
If you just want to get all the documents inside your recipe collection, you can make use of the CollectionReference.get() method (documentation).

MongoDB findOne() for retrieving from DB

I am writing code in nodejs/MongoDB and am countering this particular issue which I was hoping to get help with:
I have various schemas defined within my Models and I note that for each of these MongoDB automatically populates a unique id, which is represented by the _id field.
However, I am interested in creating a customized ID, which is basically an integer that auto-increments. I have done so by utilizing the 'mongoose-auto-increment' npm package. For example, in my UserSchema:
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
autoIncrement.initialize(mongoose.connection);
UserSchema.plugin(autoIncrement.plugin, {
model: 'UserSchema',
field: 'user_id',
startAt: 1,
incrementBy: 1
});
To speed up my application, I have a seeds.js file which aims to load a bunch of data upon application initialization. However, to make this fully functional, I need a way to access my models and reference them over to other models (for cases when there is a one-to-one and one-to-many relationship). Since the mongoDB default _id is extremely long and there is no way to get the result unless I am actually on the html page and can use the req.params.id function, I have been trying to use mongoDB's findOne function to do this without success.
For example:
var myDocument = User.findOne({user_id: {$type: 25}});
if (myDocument) {
var myName = myDocument.user_id;
console.log(myName);
}
However, the result is always 'undefined' even though I know there is a User model saved in my database with a user_id of 25.
Any help would be much appreciated :)
User.findOne({ user_id: 25 }).exec(function (err, record) {
if (err) {
console.log(err);
} else {
console.log(record);
}
});
You need to undestand the nature of Node.js.
Node.js runs in async nature so you can't get the result here.
You need to do with other ways
like:
use callback
use promise
use async/await(ES8)
Try this:
User.findOne({user_id: {$type: 25}}, function (err, myDocument) {
if (myDocument) {
var myName = myDocument.user_id;
console.log(myName);
} else {
console.log(err);
}
});

get _id with mongoose

I was trying to console.log(record._id) all of records on my mongodb collection using Mongoose. I kept getting undefined for each of the _id values.
I struggled until I bumped into this post. Then I used console.dir to find the location of the _id and used that in my console.log:
MySchemaModel.find({}).then(function(records) {
records.forEach(function(record) {
console.log(record._doc._id); // <-- I added ._doc
});
});
But, this looks down-right hacky. Is there a better way to do this?
NOTE: This isn't just something that affects console.log. I'm just keeping the question narrow.
If you want to customize/edit record then you should use .lean() function.The .lean() function will turn it into a normal JavaScript object. If you don't use .lean() function then each record is still a mongoose document and _id behaves differently in that context. So can use like
MySchemaModel.find({}).lean().exec(function(error, records) {
records.forEach(function(record) {
console.log(record._id);
});
});
N.B: when use .exec() then first parameter used for error and second one for success data.
Mongoose assigns each of your schemas an id virtual getter by default
which returns the documents _id field cast to a string, or in the case
of ObjectIds, its hexString. If you don't want an id getter added to
your schema, you may disable it passing this option at schema
construction time.
Source: Mongoose Docs
var schema = new Schema({ name: String }, { id: false });
var Page = mongoose.model('Page', schema);
var p = new Page({ name: 'mongodb.org' });
console.log(p.id); // '50341373e894ad16347efe01'
I guess the issue is with .then promise, I have never seen that.
MySchemaModel.find({}).then
So just try simple .exec call with callback.
MySchemaModel.find({}).exec(function(records) {
records.forEach(function(record) {
console.log(record._id);
});
});
The problem is that each record is still a mongoose document and _id behaves differently in that context. The .lean() function will turn it into a normal JavaScript object.
MySchemaModel.find({}).lean().then(function(records) {
records.forEach(function(record) {
console.log(record._id);
});
});
you can also use the .map() method :
MySchemaModel.find({}).exec(function(records) {
console.log(records.map(record => record._id);
});
if you are using a model you don't get the full object but an instance of _doc as record
so you should directly
console.log(record._id)
or
console.log(record._id.valueOf())
but when you return record as response you get the full object so it's better to use .find().lean()

Mongoose find() not returning result

I have a route set up that uses a model called Todo like below:
app.get('/api/todos', function(req, res) {
Todo.find({},function(err, todos) {
if (err)
res.send(err);
console.log("number of todos " + todos.length);
res.json(todos); // return all todos in JSON format
});
});
however, todos.length is always 0, as it do not find any results.
When I run:
use test3
db.Todo.find()
I am sure I have connected to the same db. I can see the connection in mongod console.
My connection is inside config/db.js file:
module.exports = {
url : 'mongodb://localhost/test3'
}
The connection in my server.js is as follows:
var db = require('./config/db');
mongoose.connect(db.url);
in Mongo Shell I get 1 result. I am expecting this result to be return by the find query.
Is there something I have missed?
I am using Mongoose 3.6
Cheers
So what this very much looks like is that you have already created collections in an existing database and now you are trying to access these with mongoose models.
The problem is that mongoose uses some defaults which you may not be aware of, so the example you are showing from the shell is not the same as what mongoose is doing by default.
So you can either rename your collections to match what mongoose expects by default or change what mongoose does to match your existing names. In the latter case, you directly define the model names like so:
mongoose.model( "Todo", toDoSchema, "Todo" );
So the third argument to the method actually specifies the explicit name to use for the collection. Without this the assumed name under the default rules will be "todos".
Use either method in order yo make them match.
I faced this exact issue, I defined the Model for an already existing collection in MongoDB and to stop Mongoose from producing a collection name in plural I used this explicit collection option. Mistakenly I wrote Collection and this halted the results. So be careful while using explicit options, they are case sensitive.

Saving a modified document (with a modified subdocument array) in Mongoose model

The code I currently have is:
User.findOne(
{
"subUsers.email" : userEmail
},
{
subUsers : {
$elemMatch: {
email : userEmail }
}
},
function(err, user){
if(user){
var information = user.subUsers[0].information.id(id);
information.arrayA.push({someId : "something"});
user.save(callback(err)); // Also tried information.save()
// without luck
}
callback(err);
}
);
This doesn't return any kind of error, but when I check the DB, the new array element hasn't been pushed (the whole document is intact).
Any help would be much appreciated. Thanks!
You should probably check out the first faq, here: http://mongoosejs.com/docs/faq.html
Mongoose doesn't create getters/setters for array indexes; without them mongoose never gets
notified of the change and so doesn't know to persist the new value. The work-around is to
use [MongooseArray set][1] available in Mongoose >= 3.2.0.
So in your case, you want to add this third line
var information = user.subUsers[0].information.id(id);
information.arrayA.push({someId : "something"});
user.subUsers.set(0, information);
Or something like that.
As of today, Mongoose is currently not prepared for multilevel nesting in an atomic way.
Therefore, even if it's going back to a kind-of relational database, in this case it's better to split the nesting into at least 2 collections, and reference using the automatically generated ObjectId.

Categories