Reputation: 509
I am using Mongodb and the stucture is as below:
**{
"_id" : ObjectId("5693af5d62f0d4b6af5124f1"),
"uid" : 1,
"terms" : [
"sasasdsds",
"test",
"abcd"
]
}**
I want to remove the last element from array if the length of it is greater than 10. Is it possible to be done in a single query?
Upvotes: 8
Views: 4639
Reputation: 50436
Yes it is possible. What you use is a property of "dot notation" to test that the array contains at least 11 members and then apply the $pop
update modifier to the array:
db.collection.update(
{ "terms.10": { "$exists": 1 } },
{ "$pop": { "terms": 1 } },
{ "multi": true }
)
So the test there is for the presence of the n-1
element in the array by index which means it must have at least that many members to match using the $exists
operator. That works opposed to $size
which is looking for an "exact" length of the array to match.
Then the $pop
with a positive integer in the argument removes the last entry from that array.
The alternate case would be where you just wanted to keep 10 entries in the array only regardless of length, where you could then apply the $slice
modifier to the $push
update operator:
db.collection.update(
{ "terms.10": { "$exists": 1 } },
{ "$push": { "terms": { "$each": [], "$slice": 10 } } },
{ "multi": true }
)
Where the maybe not obvious example with $push
is when the $each
modifier has an empty array then no changes are made (pushed) to the array, however the $slice
is applied to restrict the overall array length. In this case, from the start of the array ( first n
elements ) by using a positive integer. A negative comes from the "end" of the array for the "last" n
elements.
In each case the "multi"
modifier is used to apply the statement to all matched documents from the query condition of the update. And in both cases it's still best to just modify the documents that are a match only.
Upvotes: 13