I have some objects in Mongodb created according to this mongoose Schema
const MetalSchema = mongoose.Schema({
dia_6:{type:Number},
dia_8:{type:Number},
dia_10:{type:Number},
dia_12:{type:Number},
dia_15:{type:Number}
});
All Objects have different quantity of key:value pairs. How to get the key names which are present in Object in DB?
i think you can use something like this
MetalSchema.schema.eachPath(function(path) {
console.log(path);
});
I got index names with this code:
var mykeys;
database.findOne({}, function(result) {
mykeys = Object.keys(result._doc);
});
Great thank's for STR for his answer in neighber question
I have been trying to find out the indexes which are already created via MongoDB manually( I have created 2d sphere indexes for two fields via mongobooster and creating one via schema by defining it). Now if i run this query in mongodbooster
db.collectionname.getIndexes();
It results me the 3 documents with name.key and which indexes i have used. I want to perform this same operation in mongoose i can't find a equivalent query for the same. I tried this
const indexes = OrderSchema.indexes();
console.log('index:', indexes);
But it gives me only one index which i have defined in schema that is _id i need two other fields as well which contains 2d-sphere index how can i get that too. What am trying to achieve here is if 2d sphere indexes are already created don't create an index else create an index that's all am trying to achieve here. Any help is appreciated Thanks
Yeah, you can't do it with a schema. You will need to create the model first, and then you can do something like this:
Order.collection.getIndexes({full: true}).then(indexes => {
console.log("indexes:", indexes);
// ...
}).catch(console.error);
If you dont have access to mongoose model, but the mongoose connection was created and you need to get the indexes from a collection you can access by this way:
const mongoose = require('mongoose');
mongoose.connect('myConnectionString', { useNewUrlParser: true }).then(() => {
getIndexes();
});
const getIndexes = async () => {
const indexes = await mongoose.connection.db.collection('myCollection').
indexes.forEach(function (index) {
console.log(JSON.stringify(index));
});
};
Background: I have a mongo database named test with a collection called collection. There is a single document in test.collection:
{ "_id" : ObjectId("64e4a6f9d1d7ba45250dc2c1"), "key" : "value"}
Question: Using Mongoose, what is a way to grab the lone document found in test.collection, convert it into a javascript object, and to identify it with the variable object? For example, we should have that
console.log(object.key)
returns "value".
EDIT : I have tried the following, which didn't work:
var Schema = mongoose.Schema;
var Model = db.model('Model', mongoose.Schema({}),'collection');
var doc = Model.findOne();
console.log(doc.key); // doesn't show "value" as expected
Do it this way (as stated on my comment):
Model.find(function (err, docs) {
if (err) return console.error(err);
console.log(docs[0].key);
});
I also recommend taking another look to the docs, it's always good to refresh the basic concepts.
When I do the .find operation like the following:
Collection.find({name: 'Erik'}, function (err, docs) {
// do momething
});
'docs' variable is populated with an array of fully functional mongoose documents. But I need to get an array of pure JSON objects.
I know I can loop through the 'docs' array by forEach and get an objects by using .toJSON() method. Does mongoose support the feature, I'm interested?
If you're using Mongoose 3.x you can use the lean query option to do this:
Collection.find({name: 'Erik'}).lean().exec(function (err, docs) {
// docs are plain javascript objects instead of model instances
});
.exec(function(err, docs){
docs= docs.map(o => o.toObject());
This will include virtuals and getters
Map through results and convert each to JS object:
const result = await model.find({some: 'query'});
return result.map((r) => r.toObject());
How can I know the count of a model that data has been saved? there is a method of Model.count(), but it doesn't seem to work.
var db = mongoose.connect('mongodb://localhost/myApp');
var userSchema = new Schema({name:String,password:String});
userModel =db.model('UserList',userSchema);
var userCount = userModel.count('name');
userCount is an Object, which method called can get a real count?
Thanks
The reason your code doesn't work is because the count function is asynchronous, it doesn't synchronously return a value.
Here's an example of usage:
userModel.count({}, function( err, count){
console.log( "Number of users:", count );
})
The code below works. Note the use of countDocuments.
var mongoose = require('mongoose');
var db = mongoose.connect('mongodb://localhost/myApp');
var userSchema = new mongoose.Schema({name:String,password:String});
var userModel =db.model('userlists',userSchema);
var anand = new userModel({ name: 'anand', password: 'abcd'});
anand.save(function (err, docs) {
if (err) {
console.log('Error');
} else {
userModel.countDocuments({name: 'anand'}, function(err, c) {
console.log('Count is ' + c);
});
}
});
You should give an object as argument
userModel.countDocuments({name: "sam"});
or
userModel.countDocuments({name: "sam"}).exec(); //if you are using promise
or
userModel.countDocuments({}); // if you want to get all counts irrespective of the fields
For the older versions of mongoose, use
userModel.count({name: "sam"});
The collection.count is deprecated, and will be removed in a future version. Use collection.countDocuments or collection.estimatedDocumentCount instead.
userModel.countDocuments(query).exec((err, count) => {
if (err) {
res.send(err);
return;
}
res.json({ count: count });
});
Background for the solution
As stated in the mongoose documentation and in the answer by Benjamin, the method Model.count() is deprecated. Instead of using count(), the alternatives are the following:
Model.countDocuments(filterObject, callback)
Counts how many documents match the filter in a collection. Passing an empty object {} as filter executes a full collection scan. If the collection is large, the following method might be used.
Model.estimatedDocumentCount()
This model method estimates the number of documents in the MongoDB collection. This method is faster than the previous countDocuments(), because it uses collection metadata instead of going through the entire collection. However, as the method name suggests, and depending on db configuration, the result is an estimate as the metadata might not reflect the actual count of documents in a collection at the method execution moment.
Both methods return a mongoose query object, which can be executed in one of the following two ways. Use .exec() if you want to execute a query at a later time.
The solution
Option 1: Pass a callback function
For example, count all documents in a collection using .countDocuments():
someModel.countDocuments({}, function(err, docCount) {
if (err) { return handleError(err) } //handle possible errors
console.log(docCount)
//and do some other fancy stuff
})
Or, count all documents in a collection having a certain name using .countDocuments():
someModel.countDocuments({ name: 'Snow' }, function(err, docCount) {
//see other example
}
Option 2: Use .then()
A mongoose query has .then() so it’s “thenable”. This is for a convenience and query itself is not a promise.
For example, count all documents in a collection using .estimatedDocumentCount():
someModel
.estimatedDocumentCount()
.then(docCount => {
console.log(docCount)
//and do one super neat trick
})
.catch(err => {
//handle possible errors
})
Option 3: Use async/await
When using async/await approach, the recommended way is to use it with .exec() as it provides better stack traces.
const docCount = await someModel.countDocuments({}).exec();
Learning by stackoverflowing,
Using mongoose.js you can count documents,
count all
const count = await Schema.countDocuments();
count specific
const count = await Schema.countDocuments({ key: value });
The highest voted answers here are perfectly fine I just want to add up the use of await so that the functionality asked for can be achieved:
const documentCount = await userModel.count({});
console.log( "Number of users:", documentCount );
It's recommended to use countDocuments() over 'count()' as it will be deprecated going on. So, for now, the perfect code would be:
const documentCount = await userModel.countDocuments({});
console.log( "Number of users:", documentCount );
Model.count() method is deprecated in mongoose version 6.2.0. If you want to count the number of documents in a collection, e.g. count({}), use the estimatedDocumentCount() function instead. Otherwise, use the countDocuments() function instead.
Model.estimatedDocumentCount() Estimates the number of documents in the MongoDB collection. It is Faster than using countDocuments() for large collections because estimatedDocumentCount() uses collection metadata rather than scanning the entire collection.
Example:
const numAdventures = await Adventure.estimatedDocumentCount();
reference : https://mongoosejs.com/docs/api.html#model_Model.estimatedDocumentCount
As said before, your code will not work the way it is. A solution to that would be using a callback function, but if you think it would carry you to a 'Callback hell', you can search for "Promisses".
A possible solution using a callback function:
//DECLARE numberofDocs OUT OF FUNCTIONS
var numberofDocs;
userModel.count({}, setNumberofDocuments); //this search all DOcuments in a Collection
if you want to search the number of documents based on a query, you can do this:
userModel.count({yourQueryGoesHere}, setNumberofDocuments);
setNumberofDocuments is a separeted function :
var setNumberofDocuments = function(err, count){
if(err) return handleError(err);
numberofDocs = count;
};
Now you can get the number of Documents anywhere with a getFunction:
function getNumberofDocs(){
return numberofDocs;
}
var number = getNumberofDocs();
In addition , you use this asynchronous function inside a synchronous one by using a callback, example:
function calculateNumberOfDoc(someParameter, setNumberofDocuments){
userModel.count({}, setNumberofDocuments); //this search all DOcuments in a Collection
setNumberofDocuments(true);
}