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 },
)
Related
I have created a user which has its login data and into it is has some arrays including friends, groups, pages and other stuff.
But I am stucked when I want see who has sent me a friend request.
So I have am trying to create the friend request/response as in Facebook.
My logic it is for the moment when I send you a friend request I add to my array of friends and then with post request I can see at which users is my ID added and it has the status Pending.
For the moment I have tried something but I am getting empty array as response.
My code is below.
User model
const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const userDataScheme = new mongoose.Schema({
firstName: String,
lastName: String,
email: {
type: String,
unique: true
},
password: String,
phone: {
number: String,
countryCode: String,
dialCode: String,
e164Number: String,
internationalNumber: String,
nationalNumber: String
},
gender: Number,
birthday_day: String,
birthday_month: String,
birthday_year: String,
friends: [{
_id: false,
friendId: String,
createdDate: { type: Date, default: Date.now },
status: Number,
}
]
},
{ autoIndex: false });
userDataScheme.plugin(uniqueValidator, { message: 'Email already in use.' });
module.exports = mongoose.model('User', userDataScheme);
user.service.js backend
const User = require("../models/user");
async function findYourPendingContact({friendId}) {
return await User.find({friends: friendId});
}
module.exports = {
findYourPendingContact
}
routes.js
routes.post("/user-friends", UserController.findYourContacts);
This is the Controller.
const userService = require("../service/user.service");
async findYourContacts(req, res, next) {
let friendId = req.body.friendId;
userService.findYourPendingContact({friendId: friendId})
.then(friends => res.json(friends))
.catch(err => next(err));
}
So seems my Database Json.
The user that added me as friend.
{
"_id" : ObjectId("620bfd2d860fd314fc538df3"),
"firstName" : "Max",
"email" : "maxmuster#outlook.de",
"lastName" : "Muster",
"password" : "$2b$10$D8l15CTZHbp/rcApqXpwT.KUbHAg0hBYp0h1qounnKFW.plDO9wKe",
"phone" : {
"number" : "1234566",
"countryCode" : "DE",
"dialCode" : "+49",
"e164Number" : "+491234566",
"internationalNumber" : "+49 1234566",
"nationalNumber" : "1234566"
},
"gender" : 1,
"birthday_day" : "13",
"birthday_month" : "8",
"birthday_year" : "1998",
"friends" : [
{
"friendId" : "6204605617d5fcc3c179f3cc", // this here is my ID
"status" : 0,
"createdDate" : {
"$date" : 1644971031461
}
}
],
"__v" : 0
}
Here are my Data on backend
{
"_id" : ObjectId("6204605617d5fcc3c179f3cc"),
"firstName" : "Test",
"email" : "test.test#outlook.com",
"lastName" : "Test",
"password" : "$2b$10$koGb0fIcdWvq2ugGQXF7.OOmoof1QCH8IKQtoMGl9MHSJuu5Xumd6",
"phone" : {
"number" : "01234567",
"countryCode" : "DE",
"dialCode" : "+49",
"e164Number" : "+4901234567",
"internationalNumber" : "+49 01234567",
"nationalNumber" : "01234567"
},
"gender" : 0,
"birthday_day" : "8",
"birthday_month" : "5",
"birthday_year" : "1994",
"__v" : 0
}
Now this is the part of my frontend when I login.
public getUserFriends(userId): Observable<any> {
const api = `${this.baseUrl}/user-friends`
return this.http.post(api, JSON.stringify({friendId: userId}), this.httpOptions).pipe(
map((response: User) => {
console.log(response);
return response;
},
(err) => {
throw err;
})
)
}
user.helper.ts
showPendingFriends(authId): Observable<any> {
return new Observable<any>(observer => {
this.userService.getUserFriends({friendId: authId}).subscribe(response => {
observer.next(response);
})
})
}
components.ts
this.userHelper.showPendingFriends(this.authService.userID).subscribe(res => console.log(res)); //this.authService.userID is my ID actually 6204605617d5fcc3c179f3cc or it can be any user ID
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
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).
I have to use populate method for referencing my second collection. I have two collections one is levels and second child.
I have referenced to my level collection through child collection. For this, I use the populated method but it returns null.
This is node js code
function(){
var query = {'_id': result._id };
var params = 'usercurrLevelId';
childQuizInfo.findOne(query, params).populate({
path : 'usercurrLevelId',
model : 'Level',
select : '_id level_num age'
}).exec(function(err,levelinfo){
if(err) return next(err);
res.send(levelinfo);
});
}
This level schema
var LevelSchema = new Schema({
_id: { type: String },
age: { type: Number },
level_num: { type: Number },
min_score: { type: Number },
max_questions: { type: Number }
});
var Level = mongoose.model('Level', LevelSchema);
This is child schema
usercurrLevelId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Level',
index: true
}
This is the level stored in mongoDB
{
"_id" : ObjectId("57cb1ef8b0b05a2ce9b0c24b"),
"age" : 5,
"level_num" : 1,
"min_score" : 12,
"max_questions" : 30
}
{
"_id" : ObjectId("57cb1ef9b0b05a2ce9b0c24c"),
"age" : 5,
"level_num" : 2,
"min_score" : 15,
"max_questions" : 33
}
This is the child stored in mongoDB
{
"_id" : ObjectId("57cc0410d51045452644251b"),
"usercurrLevelId" : ObjectId("57cb1ef8b0b05a2ce9b0c24b")
}
And the output i get
{
"_id": "57cc0410d51045452644251b",
"usercurrLevelId": null,
"__v": 0
}
I using this node js query so that I get level_num and _id from my level schema using this referencing.
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')