Checked couple of old similar questions but no luck in finding the right answers.
I have a mongo query that uses await/async to fetch results from the database, So the code looks like this :
(async () => {
//get connection object
const db = await getDatabaseConnection("admindb");
//get user data object
const configResponse = await db.collection("config").find({}).toArray();
//prints results
console.log("Successfully Fetched Configuration", configResponse);
})();
The above code works fine, just that it returns me an array of elements since I have used the .toArray() method.
Sample Result:
[
{
_id: "6028d30db7ea89f74df013d9",
tokenize: false,
configurations: { theme: {} }
}
]
Is there a NATIVE WAY (not looking forEach responses) to get result as an object since I will always have only one document returned. I have multiple queries that returns only one document, Hence accessing using the 0th index everytime did not seem the right way.
I am thinking if the findOne() will help you.
Check this out docs
await db.collection("config").findOne({});
Here are some examples
I'm trying to create a query in my nodesjs server (functions section) in firebase
I created a collection with 3 documents and 2 fields each - email and timestamp
when I do a query for email -> I get the right documents
await admin.firestore().collection('sessions').where('email', '==', 'email#gmail.com').get()
when I do a query for timestamp -> I get the right documents
await admin.firestore().collection('sessions').where('timestamp', '>', 1601164800).get()
but...
when I do a query for both email and timestamp -> I get no documents...
await admin.firestore().collection('sessions').where('email', '==', email).where('timestamp', '>', 1601164800).get()
the way I understand it is when I do multiple 'where' it's like a logical AND so if I get the same records in the first query and the seconds query I should get them in the third query as well
I also read that I need to create an index in case I want to do multiple where that have an equal operator and range operator so I created one and no luck :(
all the data I created manually - both the collection + documents and the index
is there something that I miss?
collection data
indexes definition
this is the code of full process of getting the docs
the result array I return to the client and I get an empty array
async function getInfo() {
let query = admin.firestore().collection('sessions').where('email', '==', 'email#gmail.com').where('timestamp', '>', 1601164800);
let dbData = await query.get();
let result = [];
dbData.forEach(doc => {
let data = doc.data();
// this log is to see how many docs I get
logger.log(data);
result.push(data);
});
return result;
}
What about iterating over dbData.docs?
logger.log(`Documents retrieved: ${dbData.size}`)
return dbData.docs.map(doc => doc.data())
https://googleapis.dev/nodejs/firestore/latest/QuerySnapshot.html
So I'm making a search bar in my app and I'm using mongodb to fetch the results.
The situation is as following:
When the _group property (which is an ObjectId) of the post document is equal to one of the values in the exampleArray I want this post to be included in my end result. How would I do this?
const exampleArray = ['ObjectId1', 'ObjectId1', 'ObjectId1'];
const posts = await Post.find({_group: exampleArray })
The query will need to use the MongoDB $in operator, which is used to compare a field against a list of values.
Try the following:
posts = await Post.find({_group: { "$in" : exampleArray } })
Is it possible to query a returned collection in mongoose for mongodb. So in the example below I wish to return to the page the full list of steps, as well as the currentStep. The line I am unsure about is currentStep: steps.?????(page).
Thanks
var page = (req.params.page == undefined?1:req.params.page)
db.stepModel.find().sort({number:1}).exec(function(err, steps) {
if (err) { return next(err); }
res.render('scheme', {
title: 'Fnol',
user: req.user,
steps:steps,
currentStep: steps.?????(page),
page:page
});
};
You can use steps as an array:
currentStep : steps[page - 1].toObject()
The - 1 is because it seems that you use 1-based indexing for the page, whereas arrays are 0-based.
The toObject() converts the Mongoose result into a proper JS object, so you can access properties like _id from within your template.
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);
}