I am trying to remove an element from a list inside a document using the index as suggested here
db.example.update({}, [
{$set:{ sequence: {
$concatArrays:[
{$slice:[ "$sequence", P ]},
{$slice:[ "$sequence", {$add:[1,P]}, {$size:"$sequence"}]}
]
}}}
]);
However, I am having problems while trying to convert the query to the spring syntax equivalent:
Update update = new Update();
/*how do I pass the slice in the following statement?*/
ArrayOperators.ConcatArrays array = ArrayOperators.ConcatArrays.arrayOf(****);
SetOperators.SetUnion setUnion = SetOperators.SetUnion.arrayAsSet(** slice with add and size***).union(array);
update.set("sequence", setUnion);
Thanks
The second parameter to $concatArrays should look something like this.
ArrayOperators.Slice.sliceArrayOf("sequence")
.offset(P+1)
.itemCount(ArrayOperators.Size.lengthOfArray("sequence"));
Unfortunately, itemCount
accepts only int arguments, so this won't work.
If your array has distinct elements, you can try this modified query.
db.collection.update({},
[
{
"$set": {
"sequence": {
"$concatArrays": [
{
"$slice": ["$sequence",P]
},
{
"$setDifference": [
"$sequence",
{
"$slice": ["$sequence",{$add:[P,1]}]
}
]
}
]
}
}
}
])
Since you need pipelined update, you need to use AggregationUpdate
.
AggregationUpdate update = Aggregation.newUpdate()
.set("sequence")
.toValue(ArrayOperators.ConcatArrays
.arrayOf(ArrayOperators.Slice.sliceArrayOf("sequence").itemCount(P))
.concat(SetOperators.SetDifference.arrayAsSet("sequence")
.differenceTo(ArrayOperators.Slice.sliceArrayOf("sequence").itemCount(P+1))));
Another easier way is to do this in javascript using $function
db.collection.update({},[
{
$set: {
"sequence": {
$function: {
body: function(sequence) {
sequence.splice(P,1);
return sequence;
},
args: ["$sequence"],
lang: "js"
}
}
}
}
]);
AggregationUpdate update = Aggregation.newUpdate()
.set("sequence")
.toValue(ScriptOperators
.function("function(sequence) {\r\n"
+ " sequence.splice(P,1);\r\n"
+ " return sequence;\r\n"
+ "}")
.args("$sequence")
.lang("js"));