Mongoose get object in array of objects - javascript

I am using mongoose and I am trying to get users from my mongodb database, Here is what part of my json looks like
"hpCDaKverVWEYukAhAcM8NU6SP73" : {
"admin" : false,
"booksBorrowed" : [ {
"id" : "9780321831552",
"timeStamp" : 1618881802437
}, {
"id" : "9780007204496",
"timeStamp" : 1618881803678
}, {
"id" : "9780316491297",
"timeStamp" : 1618882675513
}, {
"id" : "9780440335160",
"timeStamp" : 1618882676756
}, {
"id" : "9781482287325",
"timeStamp" : 1618887153684
} ],
I am trying to get the books borrowed array
i tried creating a new schema like this
const BorrowedBook = new Schema({
id : {type: String, default: ''},
timeStamp : {type: Number, default: 0},
})
then doing this in mongoose.model
booksBorrowed: [BorrowedBook]
then I do this in server.js
const User = require('./models/user')
app.get('/api/users', function (req, res) {
User.find(function (err, users) {
console.log(users)
})
})
but it just prints this
booksBorrowed: [ [Object], [Object], [Object], [Object], [Object] ],
What am I doing wrong?

You are doing nothing wrong, its just console.log(users) printing this, since it doesnt print nested lvl objects.
You can do console.log(JSON.stringify(users)) or console.dir(users).

Related

How can I increment & add to array on mongoose

In my database, I have a user table with 2 columns: score & history :
I have another table called card containing some specific information & a card _id.
Each time a specific card is clicked, I would like the '/CardClicked' router to be called for :
Additional (increment) a specific number value (1.5) on score column
Add the cart _id value on the array of history column: (to save, which card the user clicked)
I wanted to have something like that in my database:
users:
{ "_id" : 1, "score" : 6.0, "history" : [ 62k6hf45b0af050fe, 69k5hf45b0af450fg, 65k5hf45b0af450fg, ]}
{ "_id" : 2, "score" : 4.5, "history" : [ 65k5hf45b0af450fg,] }
{ "_id" : 3, "score" : 10.0, "history" : [ 66k5hf45t0af930rp, 67k5hf45b0af450fg, 62k6hf45b0af050fe, 61y5hf884b0af450vb, ] }
But, idk why it doesn't update properly on columns, however i don't have any error, that my code i made it :
My UserSchema.js :
const mongoose = require('mongoose')
const UserSchema = new mongoose.Schema({
...
score: {
type: Number,
},
history: {
type: [String]
},
createdAt: {
type: Date,
default: Date.now,
},
})
module.exports = mongoose.model('User', UserSchema)
My router.js :
app.post('/CardClicked', async function (req, res){
console.log("User ID "+req.user._id, "Card ID : "+req.body._id);
try{
const condition = { _id: req.user._id };
//the req.body._id contain the card id from my front to send that to router
const putPostID = { $addToSet: { history: req.body._id }};
const additionalPoints = {$inc : { score : 1.5 }};
await User.findOneAndUpdate(condition, additionalPoints, putPostID, {upsert: true})
}catch(err){
res.status(500).send({error: err })
}
});
Every update operation must go into one object. In your case:
User.findOneAndUpdate(condition, {
$inc: { score: 1.5 },
$addToSet: { history: req.body._id },
},
{ upsert: true },
)

how to avoid duplicate key error collection in mongodb

i want to build a cart for my website, this is the schema for the cart:
const productSchema = require("./product")[1];
const cartItemSchema = new Schema<CartItem>(
{
product: productSchema,
quantity: {
type: Number,
required: true,
min: [1, "Quantity can not be less then 1."],
},
},
{
timestamps: true,
}
);
const CartSchema = new Schema(
{
userID: {
type: Schema.Types.ObjectId,
ref: "User",
},
items: [cartItemSchema],
},
{ timestamps: true }
);
module.exports = model<Cart>("Cart", CartSchema);
the problem is, when I add a product in a specific user cart, while the same product is allready added to another user cart document, I get this error:
"message":"cannot add to cart E11000 duplicate key error collection: elec-store.carts index: items.productID_1 dup key: { items.productID: null }, stack: MongoError: E11000 duplicate key error collection: elec-store.carts index: items.productID_1 dup key
this is the add function
public async add(cartItem: CartItem, userID: string): Promise<Cart> {
let cartInDB = null;
await CartModel.findOne({ userID: userID }, (err, cart) => {
cartInDB = cart;
});
if (AppUtils.hasValue(cartInDB)) {
const index = cartInDB.items.findIndex(
(item) => item.product._id.toString() === cartItem.product._id
);
if (index !== -1) {
cartInDB.items[index].quantity =
cartInDB.items[index].quantity + cartItem.quantity;
cartInDB.items[index].product._id = cartItem.product._id;
const cartAfterAdding = await cartInDB.save();
return cartAfterAdding;
} else {
await CartModel.update(
{ _id: cartInDB._id },
{ $push: { items: cartItem } }
);
}
return cartInDB;
} else {
const itemsArray: CartItem[] = [];
itemsArray.push(cartItem);
let createdCart = new CartModel({
userID: userID,
items: itemsArray,
});
await createdCart.save(); \\ this is where the problem occurs
return createdCart;
}
}
and this is how my cart looks like in mongodb document:
db.carts.find().pretty()
{
"_id" : ObjectId("60ea9fb81b2b4c048c3b1544"),
"userID" : ObjectId("60dee5e1da81bd274cd304de"),
"items" : [
{
"_id" : ObjectId("60ea9fb81b2b4c048c3b1545"),
"product" : {
"_id" : ObjectId("60e62cb21f74572b7c0b3a30"),
"name" : "tv",
"description" : "the best tv",
"categoryID" : 2,
"quantity" : "2",
"serialNumber" : "226swaq12",
"price" : 2000,
"imgUrl" : "https://www.seekpng.com/png/full/774-7744281_samsung-electronics-samsung-electronic-product-png.png"
},
"quantity" : 6,
"createdAt" : ISODate("2021-07-11T07:37:29.790Z"),
"updatedAt" : ISODate("2021-07-11T07:38:15.583Z")
},
{
"_id" : ObjectId("60eaa16b1b2b4c048c3b155d"),
"product" : {
"_id" : ObjectId("60e066009be1060748201ad3"),
"name" : "samsung tv",
"description" : "the best tv",
"quantity" : "2",
"categoryID" : 2,
"serialNumber" : "2212",
"price" : 2000,
"imgUrl" : "https://www.seekpng.com/png/full/774-7744281_samsung-electronics-samsung-electronic-product-png.png"
},
"quantity" : 9,
"updatedAt" : ISODate("2021-07-11T07:46:19.313Z"),
"createdAt" : ISODate("2021-07-11T07:44:43.764Z")
}
],
"createdAt" : ISODate("2021-07-11T07:37:29.792Z"),
"updatedAt" : ISODate("2021-07-11T07:46:19.314Z"),
"__v" : 0
}
I use mongoose.Schema to create new schemas and then when making reference to a different schema I do it like this:
product: { type: mongoose.Schema.Types.ObjectId, ref: 'product' },
If later you need to show also the product info (db.carts.find()), you can use populate() to replace the reference for all the product entries.
You can use upsert true.
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2
}
)
For example -
db.books.update(
{ item: "ZZZ135" }, // Query parameter
{ // Replacement document
item: "ZZZ135",
stock: 5,
tags: [ "database" ]
},
{ upsert: true } // Options
)
This may help: Mongo Update

Returning particular arrays from objects in mongodb

[
{
_id: 555,
names:['John','Doe','David']
},
{
_id: 625,
names:['David','Mark','Carl']
},
{
_id: 299,
names:['Bill','Carlos','Ventus']
}
]
How can I return only the names(object) of all the object having _id in MongoDB ?
Please help me..
model.find({_id : { $exists : 1} }, "-_id names", { lean : true })
As each document in mongoDB has _id : model.find({}, "-_id names", { lean : true }) this would be fine.
You could also use mongo aggregate as follows :
model.aggregate({ $project : { _id : 0, names : 1 })

checking if an array contains a post id in a mongodb document

Let's say I want to look up a user by their _id and check if the "liked" value (array) contains a certain post _id. How do I query the db for this action? Is it okay to just store these _id's in an array or does mongodb convention prefer something else to store as a reference to other documents?
So I just want to check if the user has the post _id in the "liked" array.
var users = new mongoose.Schema({
name : {type: String, unique : true, required : true, dropDups: true},
password : {type: String, required : true}, //hash
liked : [String],
created : {type: Date, default: Date.now}
});
Here is how I think this might look:
function checkIfLiked() {
let uname = "Jim";
let postId = "abc";
//check if $USER has `postId` in $LIKED
user.findOne({$USER: uname},{$LIKED: {$in: postId} }, function(err, results) {
//do something after check
});
}
For the user data
{ "_id" : ObjectId("56effca6e668e15e2eaa6dfe"), "liked" : [ "11", "23", "4" ], "name" : "aa" }
{ "_id" : ObjectId("56effcb1e668e15e2eaa6dff"), "liked" : [ "1", "2", "3" ], "name" : "bb" }
To check the user name aa with 4 in liked array
> db.user.find({liked: '4', name: 'aa'})
{ "_id" : ObjectId("56effca6e668e15e2eaa6dfe"), "liked" : [ "11", "23", "4" ], "name" : "aa" }
but
> db.user.find({liked: '2', name: 'aa'})
No matched result.
Is it okay to just store these _id's in an array or does mongodb convention prefer something else to store as a reference to other documents?
Mongoose population could do that, you can define the user schema as below
var users = new mongoose.Schema({
name : {type: String, unique : true, required : true, dropDups: true},
password : {type: String, required : true}, //hash
liked : [{ type: Schema.Types.ObjectId, ref: 'User' }],
created : {type: Date, default: Date.now}
});
var User = mongoose.model('User', users);

Mongoose DBrefs - Cast to ObjectId failed for value

I have a Team Schema holding details about teams, and a Match Schema to store these teams in. I am trying to make it so that the home/away teams in the Match Schema are references to the Team object. I have put my code below, I'm getting an error when saving the Team but I can't help but feel I have done something wrong with the Schema's or the saving of the Match. Can anyone help?
So far I have the following code:
Team.js extract
var Team = new Schema({
'key' : {
unique : true,
type : Number,
default: getId
},
'name' : { type : String,
validate : [validatePresenceOf, 'Team name is required'],
index : { unique : true }
}
});
module.exports.Schema = Team;
module.exports.Model = mongoose.model('Team', Team);
Match.js extract
var util = require('util');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Team = require('../schemas/Team').Schema;
var Match = new Schema({
'key' : {
unique : true,
type : Number,
default: getId
},
'hometeam' : {
type : Schema.ObjectId,
ref : 'Team'
},
'awayteam' : {
type : Schema.ObjectId,
ref : 'Team'
}
});
module.exports = mongoose.model('Match', Match);
index.js
app.get('/match', function(req, res) {
var key = 1356136550152; // Reading
Team.findByKey(key, function(err, team) {
if(err) {
res.send("An error occured");
}
if(!team) {
res.send("The team does not exist");
}
var match = new Match();
match.hometeam = team;
match.save(function(err) {
if(err) {
util.log('Error while saving Match: ' + util.inspect(err));
res.send("An error occured whilst saving the match");
} else {
res.send("Saved the match");
}
});
});
});
ERROR:
Error while saving Match: { message: 'Cast to ObjectId failed for value "{ name: \'testTeam\',\n _id: 50d500663ca6067226000001,\n __v: 0,\n key: 1356136550152 }" at path "hometeam"',
name: 'CastError',
type: 'ObjectId',
value:
[ { name: 'testTeam',
_id: 50d500663ca6067226000001,
__v: 0,
key: 1356136550152 } ],
path: 'hometeam' }
Error with team._id
Error while saving Match: { [MongoError: E11000 duplicate key error index: testdb.matches.$team.name_1 dup key: { : null }]
name: 'MongoError',
err: 'E11000 duplicate key error index: testdb.matches.$team.name_1 dup key: { : null }',
code: 11000,
n: 0,
connectionId: 8,
ok: 1 }
db.matches.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "testdb.matches",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"key" : 1
},
"unique" : true,
"ns" : "testdb.matches",
"name" : "key_1",
"background" : true,
"safe" : null
},
{
"v" : 1,
"key" : {
"team.key" : 1
},
"unique" : true,
"ns" : "testdb.matches",
"name" : "team.key_1",
"background" : true,
"safe" : null
}
]
In index.js it should be:
match.hometeam = team._id;
instead of:
match.hometeam = team;
UPDATE
Regarding the new error message, it looks like you have a unique index on the matches collection that refers to fields that don't exist. Drop it in the shell using:
db.matches.dropIndex('team.name_1')

Categories