await Cart.update(
{ $elemMatch: { user_id: decoded._id } },
{
$addToSet: {
"cart.&.items": {
product_id: req.query.product_id,
quantity: 1,
},
},
}
);
My goal is to add elements to the array of items in the cart.
There's no syntax with & sign. MongoDB offers $ as a positional operator which allows you to modify existing item but you don't needed since you just want to append a new object to an array, try:
{
$addToSet: {
"cart.items": {
product_id: req.query.product_id,
quantity: 1,
}
}
}
Cart.updateMany(
{ user_id: decoded._id },
{
$push: {
"cart.items": {
product_id: req.query.product_id,
quantity: 1,
},
},
}
)
I finally found the right method through trial and error.
Related
I did a lot of research on MongoDB aggregation grouping, but couldn't find a solution.
I have the following document structure:
{
"_id":"6053e0ef22b8e60015a23da8",
"shoppinglist":[
{
"_id":"606ae2e34e4416001538104f",
"items":[
{
"_id":"6071c5ed8f669f0015e6eebe",
"product_id":"605852c28ea29f0015653d6f",
},
...
]
}
}
My goal is to group the items in each shopping list object using the product_id, so that my result looks like this:
{
"_id":"6053e0ef22b8e60015a23da8",
"shoppinglist":[
{
"_id":"606ae2e34e4416001538104f",
"items":[
{
"_id":"6071c5ed8f669f0015e6eebe",
"product_id":"605852c28ea29f0015653d6f",
"count": 3 //3 items with the product_id = 605852c28ea29f0015653d6f
},
...
]
}
}
Can someone help me with this, I'm desperate.
$unwind deconstruct shoppinglist array
$unwind deconstruct shoppinglist.items array
$group by _id and product_id, and get required fields using $first and get count using $sum
$group by _id and shoppinglist._id and reconstruct array of items
$group by _id and reconstruct array of shoppinglist
db.collection.aggregate([
{ $unwind: "$shoppinglist" },
{ $unwind: "$shoppinglist.items" },
{
$group: {
_id: {
_id: "$_id",
product_id: "$shoppinglist.items.product_id"
},
shoppinglist_id: { $first: "$shoppinglist._id" },
items_id: { $first: "$shoppinglist.items._id" },
count: { $sum: 1 }
}
},
{
$group: {
_id: {
_id: "$_id._id",
shoppinglist_id: "$shoppinglist_id"
},
items: {
$push: {
items_id: "$items_id",
product_id: "$_id.product_id",
count: "$count"
}
}
}
},
{
$group: {
_id: "$_id._id",
shoppinglist: {
$push: {
_id: "$_id.shoppinglist_id",
items: "$items"
}
}
}
}
])
Playground
This is some data which is stored in a mongoDB document:
{
_id: "123"
order: 1
parent: "Dueqmd64nTxM3u9Cm"
type: "article"
unit: "kg"
}
While all the saved data will be calculated and validated first (that's why I don't use only data = { order: 2 }), I'm using the complete object to update the document:
var data = {
order: 2
parent: "Dueqmd64nTxM3u9Cm"
type: "article"
unit: "kg"
}
Collection.update(
{ _id: 123 },
{ $set: data }
);
This is working.
But if I want to remove some values, it doesn't work:
var data = {
order: 2
parent: "Dueqmd64nTxM3u9Cm"
type: "article"
unit: undefined
}
Collection.update(
{ _id: 123 },
{ $set: data }
);
I'm expecting the unit-field to get removed. But that isn't the case...
To remove fields, use the $unset operator:
data = {
unit: ""
};
Collection.update(
{ _id: 123 },
{ $set: data }
);
let items = [
{
name: "Choco",
id: "12344",
qty: 24,
status: "open"
},
{
name: "Mils",
id: "12346",
qty: 5,
status: "open"
},
{
name: "boom",
id: "12345",
qty: 10,
status: "open"
}
];
Given the array above, is it possible to update the document without calling a forEach on each of them.
For instance what i am currently doing is this
_.each(items, function( item ) {
Orders.update({_id: doc.orderId, "items.id": item.id},
{
"$set": {
'items.$.status': item.status,
'items.$.qty': item.qty,
}
})
})
is it possible to just update the entire array at once without create a new mongo db transaction
You can read all the order:
var order = Orders.findOne({_id: doc.orderId});
Than adjust order.items with the new data and then update in a single operation:
Orders.update({_id: doc.orderId },{"$set": {items:order.items}});
Do I have to do two updates, if I want to unset one value and set another value? Or is it possible to merge both together?
Collection.update(
{ _id: id },
{ $unset: { 'status.editing': '' } }
);
Collection.update(
{ _id: id },
{ $set: { 'status.version': timestamp } }
);
How about
Collection.update(
{ _id: id },
{
$unset: { 'status.editing': '' },
$set: { 'status.version': timestamp }
}
);
See $unset and $set
It is also possible to set or unset multiple fields at the time with
{ $unset: { quantity: "", instock: "" } }
or
{ $set:
{
quantity: 500,
details: { model: "14Q3", make: "xyz" },
tags: [ "coats", "outerwear", "clothing" ]
}
}
I want to update an element of an array inside mongodb's document (I am using mongoose). Schema is something like:
{
..
arr : [{
foo: Number,
bar: [String],
name: String
}]
..
}
And my query is:
SomeModel.update({
_id: "id of the document",
arr: {
$elemMatch: {
_id: "_id assigned by mongoose to array element"
}
}
}, {
'arr.$': {
name: 'new name'
}
}).exec()
It just replaces whole array element say:
{
_id: "some objectId",
name: 'old name',
foo: 0,
}
to:
{
name: 'new name'
}
what I want:
{
_id: "some objectId",
name: 'new name',
foo: 0,
}
What I am curious to know if it is possible to achieve this in single update query ? (May be there is a silly mistake in my query :P or another approach)
I would also like to do update query like so:
{
$inc: { foo: 1},
$push: { bar: "abc"}
}
If you are still struggling with the whole implementation the full application of your statement is as follows:
SomeModel.update(
{
"arr._id": "123"
},
{
"$set": { "arr.$.name": "new name" },
"$inc": { "arr.$.foo": 1},
"$push": { "arr.$.bar": "abc" }
}
)
,function(err,numAffected) {
});
So each operation is performed in turn.