To use Mongoose find() with sort() and limit() - node.js

I want to get part of the data and it works, But when I tried to use limit() & sort() query, it's not working.
I want five data sorted by date. And it should be only 'login bio avatar_url' data. to reduce data.
But there also no error message, so I cannot find where the error from.
[My Code]
let User = require('../lib/models/userModel');
router.get("/", function (req, res, next) {
console.log(`HOME ROUTE!`);
User.find({}).limit(5).sort({
created_at: -1
}), 'login bio avatar_url', (function (err, result) {
if (err) return handleError(err);
console.log(result);
res.render('main', {
dataarray: result,
_user: req.user
})
})
});
The structure of my data looks like this.
[DATA]
{
"_id": {
"$oid": "5ebbcc92ae44dd149c12faf3"
},
"login": "apple",
"id": 10639145,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjEwNjM5MTQ1",
"avatar_url": "https://avatars0.githubusercontent.com/u/10639145?v=4",
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Cut useless data]
"name": "Apple",
"company": null,
"blog": "https://apple.com",
"location": "Cupertino, CA",
"email": null,
"hireable": null,
"bio": null,
"public_repos": 85,
"public_gists": 0,
"followers": 0,
"following": 0,
"created_at": "2015-01-21T20:19:28Z",
"updated_at": "2020-05-01T14:38:33Z"
}
When I tried to access / path, console only shows the this log.

Solved with this code. I think it's sequence problem
let User = require('../lib/models/userModel');
router.get("/", function (req, res, next) {
console.log(`HOME ROUTE!`);
User.find({},'login bio avatar_url', {limit:5}).sort({created_at:-1}).exec(function (err, result) {
if (err) console.log(err);
console.log(result);
res.render('main', {
dataarray: result,
_user: req.user
})
})
});

Related

How to pull out object heading from an array

I have a JSON response structure like this
{
"_id": "620e97d76ca392a43097cca6",
"user": "620295cbd67ece90802d2522",
"orderId": "EnrL7C",
"Items": [
{
"product": {
"name": "Fresh Salad",
"id": "61f2911723ff35136c98ad3e"
},
"quantity": 1,
"price": 1250,
"_id": "620e97d76ca392a43097cca7"
},
],
}
But i want the product not to be an object, so it should look like this
{
"_id": "620e97d76ca392a43097cca6",
"user": "620295cbd67ece90802d2522",
"orderId": "EnrL7C",
"Items": [
{
"name": "Fresh Salad",
"id": "61f2911723ff35136c98ad3e",
"quantity": 1,
"price": 1250,
"_id": "620e97d76ca392a43097cca7"
},
],
}
This is my code responsible for the response output
exports.getOrder = (req,res) => {
Order.findOne({orderId: 'EnrL7C'})
.populate("Items.product", "name")
.exec((error, order) => {
if(error) return res.status(400).json({ error });
if (order) {
return res.json(order);
}else{
return res.json(['No order found']);
}
});
Sometimes when I'm too lazy to look up all the mongoose documentation and figure out what version I'm on etc, I use the .lean() to just convert it to a normal JS object, which I'm way more comfortable with.
exports.getOrder = (req, res) => {
Order.findOne({ orderId: "EnrL7C" })
.lean() // add lean
.populate("Items.product", "name")
.exec((error, order) => {
if (error) return res.status(400).json({ error });
if (order) {
// fix the structure in javascript
order.Items = order.Items.map((item) => {
const flat = {
...item.product,
...item,
};
delete flat.product;
return flat;
});
return res.json(order);
} else {
return res.json(["No order found"]);
}
});
};
Let me know if that doesn't work, so I can update the answer.

How to speed up node service

I have two collections categorytypes and categories, each category type has multiple categories. When I am fetching all category details in each index of category there should be a a filed of category_type giving all details of category_type.
My code is:
exports.findAllWithParentChild = (req, res) => {
let resData = [];
Models.Category.find()
.then(data => {
var results = [];
async.each(data,function(cat,callback) {
console.log(cat.categorytype_id)
Models.CategoryType.findOne({'_id' : mongoose.Types.ObjectId(cat.categorytype_id)},function(err,catType) {
var obj = cat.toObject();
obj.category_type = catType;
results.push(obj);
callback(err);
});
},
function(err) {
if (err) throw err;
res.send({
response: true,
message: "Category deleted successfully.",
data : results
});
});
});
};
And the format I need in response:
{
"_id": "5cb78c44ede6452278d13fbe",
"title": "fhhghgf",
"description": "hgfhgf",
"slug": "hgfhgfhgf",
"categorytype_id": "5cb78ba8ede6452278d13fb6",
"user_id": "hgfhgfh",
"status": true,
"created_at": "2019-04-17T20:27:48.821Z",
"updated_at": "2019-04-17T20:27:48.821Z",
"__v": 0,
"category_type": {
"_id": "5cb78ba8ede6452278d13fb6",
"title": "asde",
"description": "asde",
"slug": "asde",
"user_id": "asde",
"status": true,
"created_at": "2019-04-17T20:25:12.863Z",
"updated_at": "2019-04-17T20:25:12.863Z",
"__v": 0
}
},
Is there any better way? Thanks for your assistance.
Change your code with below one and check the output
exports.findAllWithParentChild = (req, res) => {
Models.Category.find({}).
populate('categorytypes').
exec(function (err, data) {
if (err) return handleError(err);
console.log('Success', data);
});
};

Using two apis one with object id and another with name

I have two api calls to retrieve data from the same collection using different parameters.
The first one is by the ObjectID:
app.get('/api/employees/:id', function(req, res){
Employee.findOne({_id:req.params.id}, function(err, employee){
if(err)
res.send(err);
res.json(employee);
}); });
And the second one retrieves data by the name :
app.get('/api/employees/:name', function(req, res){
Employee.findOne({name:req.params.name}, function(err, employee){
if(err)
res.send(err);
res.json(employee);
});});
I placed both Apis in my code, but only the first one is being called. If I run my code I have something like:
{
"_id": "58b00dd47689fc2f48b9baf4",
"name": "Rohtih",
"dept": "CSE",
"area": "Banglore",
"contact": "9962938489",
"status": "System Engineer",
"salary": "30000",
"__v": 0
},
My mongo collection looks Like this:
{
"_id": "58b00dd47689fc2f48b9baf4",
"name": "Rohtih",
"dept": "CSE",
"area": "Banglore",
"contact": "9962",
"status": "System Engineer",
"salary": "30000",
"__v": 0
},
{
"_id": "58b00df07689fc2f48b9baf5",
"name": "Vaibhav",
"dept": "CSE",
"area": "Banglore",
"contact": "819",
"status": "Manager",
"salary": "300000",
"__v": 0
}
I would like to know how do I use both apis at a time? Is there a mistake in my code, please help me solving this?
As I could understand from your code, you may receive both parameters but you don't know when to use what. What I would separate in two different api calls:
First one is to find by Id:
app.get('/api/employees/findById', function(req, res){
Employee.findOne({_id:req.params.id}, function(err, employee){
if(err)
res.send(err);
res.json(employee);
}); });
Second one is to find by name:
app.get('/api/employees/findByName', function(req, res){
Employee.findOne({name:req.params.name}, function(err, employee){
if(err)
res.send(err);
res.json(employee);
});});
If you don't like any of those approaches, you can leave as it is and verify if the parameters are present, for example:
app.get('/api/employees/find', function(req, res){
let name = req.params.name;
let id = req.params.id;
if(name !== undefined) {
//Find By name here
} else if(id !== undefined) {
//Find by id here
}
}
Hope my answer was helpful.
One approach you can take is determine the value of the req.params.id string if it's a valid ObjectId and then create a query based on the outcome. For example:
app.get('/api/employees/:id', function(req, res){
var query = {};
if (mongoose.Types.ObjectId.isValid(req.params.id)) {
query._id = req.params.id;
} else {
query.name = req.params.id;
}
Employee.findOne(query, function(err, employee){
if(err)
res.send(err);
res.json(employee);
});
});

Not getting id from other collection using mongodb and node.js

I am adding products under particular userId but not getting userId from other collection.
api.js
var insertDocument = function(db, callback) {
db.collection('proInfo').insertOne( {
"Product_Name": json.Product_Name,
"Brand": json.Brand,
"Color": json.Color,
"Image": json.Image,
"Price": json.Price,
"Rating": json.Rating,
"Description": json.Description,
"Category": json.Category,
"Url": urla,
**"userId":db.collection('users').findOne()[0]._id,**
}, function(err, result) {
assert.equal(err, null);
console.log("Inserted a document into the proInfo collection.");
callback(result);
});
};
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
db.close();
});
});
You have to request the user from the datbase after inserting it.
e.g. based on your code the following should work:
var insertDocument = function(db, callback) {
// Based on your code we assume that you have only one user in the database. Otherwise you have to do a find for a specific user.
db.collection('users').findOne(function (err, user) {
if (err) { return callback(err); }
db.collection('proInfo').insertOne( {
"Product_Name": json.Product_Name,
"Brand": json.Brand,
"Color": json.Color,
"Image": json.Image,
"Price": json.Price,
"Rating": json.Rating,
"Description": json.Description,
"Category": json.Category,
"Url": urla,
"userId": user._id
}, function(err, result) {
assert.equal(err, null);
console.log("Inserted a document into the proInfo collection.");
// Below I am passing the error as a first param to your callback. You can implemented as you wish, but it is a convention to use error as a first param.
callback(err, result);
});
});
};

Finding a MongoDB document by different types with Mongoskin

This is an example of document that I have in my MongoDB:
{
"_id": ObjectId('5525039895884d66710d0fc3'),
"prid": "63527",
"data": {
"sku": "HF22-81639",
"name": "Product Test",
"ean": "8763900872512",
"description": "This product is my first test",
}
}
I want to make several search methods, where the search criteria are search by SKU, EAN or PRID. I created the methods but do not work, this is the example of one of the methods that I created and it does not work, just find the first document of my database but without any search criteria.
This search for "_id" if it works perfectly:
// GET - "_id"
app.get("/:id", function(req, res, next) {
req.collection.findOne({
_id: id(req.params.id)
}, function(e, result) {
if(e) return next(e);
res.send(result);
});
});
This search for "sku" does not work (this is where I need help):
// GET - "sku"
app.get("/sku/:id", function(req, res, next) {
req.collection.findOne({
sku: id(req.params.sku)
}, function(e, result) {
if(e) return next(e);
res.send(result);
});
});
Not sure how your id() function is defined but you could try:
// GET - "sku"
app.get("/sku/:id", function(req, res, next) {
req.collection.findOne({
"data.sku": req.params.id
}, function(e, result) {
if(e) return next(e);
res.send(result);
});
});
In your original code, req.params.sku is undefined because the req.params object doesn't have the field sku. From the url, only the req.param.id field is defined (from this => "/sku/:id"). So for example, if you test your API with this url:
http://localhost:3000/sku/HF22-81639
will bring back the document:
{
"_id": ObjectId('5525039895884d66710d0fc3'),
"prid": "63527",
"data": {
"sku": "HF22-81639",
"name": "Product Test",
"ean": "8763900872512",
"description": "This product is my first test",
}
}

Resources