Reputation: 146
Hello I am trying to add an element to an array that is inside an object and the object in turn inside an array, below is the structure.
// Schema called "Team" with mongoose
category: [
{
seasson: { type: String, required: true },
categories: [{ type: String, required: true }]
}]
// In code looks like:
[
{
seasson: "The seasson name 1",
categories: ["categoryOne", "categoryTwo"]
}
{
seasson: "The seasson name 2",
categories: ["categoryOne"] // I want to make push in this array the value "categoryTwo"
},
]
// I´m trying something like following code:
const status = await Team.updateOne(
{
_id: mongoose.Types.ObjectId(teamId),
},
{ $addToSet: { "category.$last.categories": "categoryTwo"} }
)
Whenever an array has to be pushed into the object, it will be in the last position of the main array. Honestly, I've been trying to find a way for a while, but I can't think of anything that works. Thanks in advance.
Upvotes: 1
Views: 1005
Reputation: 36134
There is no straight way to update the last element of the array without any identity, you can use update with aggregation pipeline starting from MongoDB 4.2,
$map
to iterate loop of category
array$mergeObjects
to merge current category
object with updated categories
field$last
to get the last element value from category.seasson
$cond
check condition if above last element's value and current object session
matches then do update operation otherwise return existing values$setUnion
to concat new value of categories
, if it is present then it will do replacelet category = "categoryTwo";
const status = await Team.updateOne(
{ _id: mongoose.Types.ObjectId(teamId) },
[{
$set: {
category: {
$map: {
input: "$category",
in: {
$mergeObjects: [
"$$this",
{
categories: {
$cond: [
{
$eq: [
{ $last: "$category.seasson" },
"$$this.seasson"
]
},
{ $setUnion: ["$$this.categories", [category]] },
"$$this.categories"
]
}
}
]
}
}
}
}
}]
)
Upvotes: 1
Reputation: 8705
The bellow query,adds "categoryTwo" in categories,of the last member of array category.I think this is what you want.
If you can next time give the document in the initial form,describe the query you want,and give the document in the final form,in valid JSON so people can help you easier.
You can try the code here Its pipeline update,needs MongoDB >= 4.2
Data in(Collection)
[
{
"_id": 1,
"category": [
{
"seasson": "The seasson name 1",
"categories": [
"categoryOne",
"categoryTwo"
]
},
{
"seasson": "The seasson name 2",
"categories": [
"categoryOne"
]
},
]
}
]
Query
db.collection.update({
"_id": {
"$eq": 1
}
},
[
{
"$addFields": {
"category": {
"$let": {
"vars": {
"without_last": {
"$slice": [
"$category",
0,
{
"$subtract": [
{
"$size": "$category"
},
1
]
}
]
},
"last_member": {
"$arrayElemAt": [
{
"$slice": [
"$category",
-1,
1
]
},
0
]
}
},
"in": {
"$concatArrays": [
"$$without_last",
[
{
"$mergeObjects": [
"$$last_member",
{
"categories": {
"$concatArrays": [
"$$last_member.categories",
[
"categoryTwo"
]
]
}
}
]
}
]
]
}
}
}
}
}
])
Results
[
{
"_id": 1,
"category": [
{
"categories": [
"categoryOne",
"categoryTwo"
],
"seasson": "The seasson name 1"
},
{
"categories": [
"categoryOne",
"categoryTwo"
],
"seasson": "The seasson name 2"
}
]
}
]
Upvotes: 1