Adding multiple $<identifier> in filterArray to update a field in nested subdocument - spring-data-mongodb

Sample JSON:
{
"animalID":"1234"
"species" :
[
{
"speciesID" : "1"
"speciesName" : "Cannines",
"subspecies" :
[
{
"subspeciesID: "1",
"subspeciesName" : "Siberian Husky"
},
{
"subspeciesID: "2",
"subspeciesName" : "Labrador"
}
]
}
]
}
If I run this below query in mongodb 4, I am getting the desire result
db.animals.update(
{"animalID":"1234"},
{ $set:{"species.$[element].subspecies.$[subspecies].spieceName","German Shepard"}},
{ arrayFilters : [{"element.speciesID":"1"},{"subspecies.subspeciesID":"1"} ] }
)
I am using spring boot 2.2.0.M4. I am trying to achieve the same in springboot application but with no luck
Update update = new Update();
update.set(species+"$[element]"+subspecies+"$[subspecies]"+spicemenName,"German Shepard")
.filterArray(Criteria.where("element.spiciesID").is("1")
.andOperator(Criteria.wher("subspicies.subspeciesID").is("1")))
mongoTemplate.findAndModify(query, update, new FindAndModifyOptions().returnNew(true), Animal.class);
I am not sure on how to pass two identifiers in filterArray.
If I pass using andOpertor I am getting an error:
Error parsing array filter :: caused by :: Expected a single top-level field name, found 'element' and 'subspecies'' on server localhost:27017
Could anyone please let me know what I am missing here.

You can chain multiple filterArray() statements
Update update = new Update();
update.set(species+"$[element]"+subspecies+"$[subspecies]"+spicemenName,"German Shepard")
.filterArray(Criteria.where("element.spiciesID").is("1"))
.filterArray(Criteria.where("subspicies.subspeciesID").is("1"))
mongoTemplate.findAndModify(query, update, new FindAndModifyOptions().returnNew(true), Animal.class);

Update update = new Update();
update.set(species+"$[element]"+subspecies+"$[subspecies]"+spicemenName,"German Shepard")
.filterArray(Criteria.where("element.spiciesID").is("1"))
.filterArray(Criteria.where("subspicies.subspeciesID").is("1"))
mongoTemplate.findAndModify(query, update, new FindAndModifyOptions().returnNew(true), Animal.class);
Metodo acima não funciona :)

Related

Mongo update multiple fields of an object which is inside an array

Using Mongo findOneAndUpdate, I am trying to update just some fields in an object from array of objects.
My object:
mainObject:{
_id: '123',
array:[
{title:'title' , name:'name', keep:'keep'},
{title:'title', keep:'keep'},
]
}
I want to change title and name for the first object in array, and keep the keep field unchanged.
This is my closest approach using Positional Operator:
// here i set dynamic arguments for query update
// sometimes i need to update only one field, sometime i need to update more fields
// also, is there a better way to do this?
let title
let name
if (args.title) {
title = { title: args.title };
}
if (args.name) {
name= { name: args.name};
}
db.Test.findOneAndUpdate(
{ _id: args.id, 'mainObject.array.title': args.title},
{
$set: {
'mainObject.array.$[]': {
...title,
...name
}
}
}
)
this problem is that it replace the whole object, the result is:
mainObject:{
array:[
{title:'changed' , name:'changed'}, //without keep... :(
{title:'title', keep:'keep'},
]
}
Should I use aggregation framework for this?
It has to be like this :
db.test.findOneAndUpdate({'mainObject.array.title': 'title'},
{$set : {'mainObject.array.$.title':'changed','mainObject.array.$.name': 'changed'}})
From your query, $ will update the first found element in array that matches the filter query, if you've multiple elements/objects in array array then you can use $[] to update all of those, let's see your query :
'mainObject.array.$[]': {
...title,
...name
}
Major issue with above query is that it will update all the objects in array array that match the filter with below object :
{
...title,
...name
}
So, it a kind of replace entire object. Instead use . notation to update particular values.

Mongodb $rename creates new field but old field remains in document

Can you tell me please what am I doing wrong when I renaming document fields? I do it via command
db.events.update( { "ico": {$exists: false} }, { $rename: { 'icos': 'ico' } } )
The problem is that the old icos value remains in document. I dont understand why if we are talking about renaming. It maens rename not create new one and keep the old field.
Tanks.
You doing everything is correct only one think. If you need to update more than one document please use updateMany extend update.
db.events.updateMany(
{
"ico": {
$exists: false
}
},
{
$rename: {
"icos": "ico"
}
}
)

Elasticsearch : Set the number of the elements of an array in a field

I'm trying to store the number of elements of an array into a field with an update. (updating the record with the count of the array).
Like for example
{
array = [ { "a" : "b" }, { "c" : "d" } ]
nb_elements = 2
}
I have tried an update with the following script
{
"script" : "ctx._source.nb_elements= ctx._source.array.values.length"
}
But it don't work.
I also tried :
{
"script" : "ctx._source.nb_elements = count",
"params" : {
"count" : ctx._source.array.values.length
}
}
But i wasn't more successfull.
Does anybody know if this is possible and if, how to do it ?
First of all you need to enable dynamic scripting by adding script.disable_dynamic: false to your config file.
Secondly, I'm supposing that you are using groovy (It's the default scripting language from 1.4).
Using the update api with this script should work:
{
"script": "ctx._source.nb_elements=ctx._source.array.size"
}

MongoDB : "unexpected token" error when trying to Update document field that is an array

I have a collection called Names with a document that looks like this:
{
"_id":33,
"listOfNames" : ["John", "Fred", "Andy"]
}
I am trying to do an update command that looks like the following:
db.Names.update{{}, {$set: {"listOfNames" : ["John", "Mary"]}, {multi:true})}
This fails with "unexpected token". What is the correct syntax to use when updating a field in a series of documents when the field is an array?
use this query
db.Names.update({},
{
$set: {"listOfNames":["John", "Mary"]},
}, { multi : true })
Anyway you put redundant { after update function, You should use (
And you put ) in wrong place

Add new attribute to the existing JSON array in Node

I want to insert one or more attributes into the existing JSON. Here's the basic format.
var resultData = {
"result" : "OK",
"data" : [
{"name1" : "value1"},
{"name2" : "value2"}
]
};
And I want to insert {"name3" : "value3"} into the end of the data field. The result should look like this.
var resultData = {
"result" : "OK",
"data" : [
{"name1" : "value1"},
{"name2" : "value2"},
{"name3" : "value3"}
]
};
How do I do this? I know how to add an attribute to the resultData or resultData.result or resultData.data.name1 or etc. However, I couldn't find a way to add an attribute to the resultData.data.
You can do:
resultData.data[3] = {"name4" : "value4"}
That would add a new element on the 4th position.
And like Sigorilla just answered before me, .push() will always add it one the end of your object.
You don't need to do resultData["data"].push() though, as you can just use resultData.data.push() I think.
You can use push(): resultData["data"].push({"name3": "value3"});

Resources