I have a collection with the document of this structure:
{
"_id": {
"$oid": "63e8af476a3674484ea14888"
},
"my_id": 321123,
"version": 0,
"parameters": [
{"a": 1},
{"a": 1, "b": 2}
]
}
Using a RESTful API the user can change the version
field to any number between 0 and len(parameters)
. Another endpoint let the user push an object to parameters
and set version
to the new len(parameters) - 1
. So using the previous example, after using this endpoint we will get:
{
"_id": {
"$oid": "63e8af476a3674484ea14888"
},
"my_id": 321123,
"version": 2,
"parameters": [
{"a": 1},
{"a": 1, "b": 2},
{"a": 1, "b": 2, "c": 3}
]
}
I tried many things, but nothing seems to work. Here are examples of what I tried:
db.parameters.findOneAndUpdate({"my_id": 321123}, {"$inc":{version: parameters}, "$push":{"a": 1, "b": 2, "c": 3}}, upsert=true)
db.parameters.findOneAndUpdate({"my_id": 321123}, {"$inc":{version: {"$size": parameters}}, "$push":{"a": 1, "b": 2, "c": 3}}, upsert=true)
As your update requires referring to another field, you have to use the update query with the aggregation pipeline.
For the first scenario,
Add a new parameter object by combining it with the current parameters
array via $concatArrays
.
I don't think that increment is what you need, but rather update the version
value via $set
stage. An example as below is to compare the version
param between the range of 0 and len(parameters)
, if true, then update with the version
param, else update with the size of the parameters
array.
db.parameters.update({
"my_id": 321123
},
[
{
"$set": {
parameters: {
"$concatArrays": [
"$parameters",
[
{
"a": 1,
"b": 2,
"c": 3
}
]
]
}
}
},
{
"$set": {
version: {
$cond: {
if: {
$and: [
{
$gt: [
2,
// version
0
]
},
{
$lt: [
2,
// version
{
$size: "$parameters"
}
]
}
]
},
then: 2,
else: {
$size: "$parameters"
}
}
}
},
}
],
{
upsert: true
})
Demo (1st scenario) @ Mongo Playground
For the second scenario,
Add a new parameter object by combining it with the current parameters
array via $concatArrays
.
Set the version
with the size of parameters
array minus 1.
db.parameters.update({
"my_id": 321123
},
[
{
"$set": {
parameters: {
"$concatArrays": [
"$parameters",
[
{
"a": 1,
"b": 2,
"c": 3
}
]
]
}
}
},
{
"$set": {
version: {
"$subtract": [
{
$size: "$parameters"
},
1
]
}
},
}
],
{
upsert: true
})