Hi everyone,
I have the following document schema:
{
"_id": ObjectId("640c64740fb9216e3a1bd565"),
"outer_field": {
"some_field_1": ["apple", "orange"],
"some_field_2": ["lemon", "orange"],
"some_field_3": [],
"some_field_4": ["apple"],
"some_field_5": ["orange"],
...
}
}
I would like to $pull
a speicfic value, let’s say apple
, from all the arrays in the inner fields of outer_field
but I’m unsure how to reference the inner fields since they’re unknown to me.
My initial thoughts are this query:
db.coll.update({}, {
"$pull": {
"outer_field.*": "apple"
}
})
where *
would match any/all fields and update all of them accordingly.
The expected result would be something like this:
{
"_id": ObjectId("640c64740fb9216e3a1bd565"),
"outer_field": {
"some_field_1": ["orange"],
"some_field_2": ["lemon", "orange"],
"some_field_3": [],
"some_field_4": [],
"some_field_5": ["orange"],
...
}
}
Thank you.
turivishal
(Vishal Turi)
March 12, 2023, 6:40am
#2
Hello @loay_khateeb ,
There is no straight way, but you can use an update with aggregation pipeline starting from MongoDB4.2,
$objectToArray
to convert the object to an array of objects in key-value format
$map
to iterate loop of above converted object
$filter
to iterate loop of array values and check condition that value not equal to “apple”
$arrayToObject
to convert back to an object from an array of object
db.coll.update({},
[
{
$set: {
outer_field: {
$arrayToObject: {
$map: {
input: { $objectToArray: "$outer_field" },
in: {
k: "$$this.k",
v: {
$filter: {
input: "$$this.v",
cond: {
$ne: ["$$this", "apple"]
}
}
}
}
}
}
}
}
}
])
Out of the question, I would suggest you improve your schema as below, which is called attribute pattern , and this will cover almost straight operations,
{
"_id": ObjectId("640c64740fb9216e3a1bd565"),
"outer_field": [
{
"field": "some_field_1",
"value": ["apple", "orange"]
},
{
"field": "some_field_2",
"value": ["lemon", "orange"]
},
{
"field": "some_field_3",
"value": []
},
{
"field": "some_field_4",
"value": ["apple"]
},
{
"field": "some_field_5",
"value": ["orange"]
}
]
}
And your query would be:
db.coll.update({},
{
$pull: {
"outer_field.$[].value": "apple"
}
})
1 Like
After some research, I’ve decided to use the attribute pattern.
Thank you for the reply, @turivishal .
1 Like
system
(system)
Closed
March 20, 2023, 9:14am
#4
This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.