Vikitor
Vikitor

Reputation: 93

How to update document in Mongo without loosing data in a Spring Mongotemplate project

I am new to Spring and MongoDB. I am trying to update a document, but every time I update some fields, the others disappear.

This is my current method:

    public UpdateResult updateCentro(String id, JsonNode jsonNode) {
        ObjectId objectId = new ObjectId(id);
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(objectId));
        Update update = Update.fromDocument(JsonNodeToDocumentConverter.INSTANCE.convert(jsonNode));
        return mongoTemplate.updateFirst(query, update, "centros");
    }

If the object that I give to the update method has 3 fields to be updated, in the database it leaves me those 3, but it deletes all the others.

I am trying to do something like this, but using mongoTemplate in Spring:

db.foo.update({"_id" :ObjectId("4e93037bbf6f1dd3a0a9541a") },{$set : {"key1":"value1",""key2":"value2",....}})

Upvotes: 1

Views: 3905

Answers (2)

Vikitor
Vikitor

Reputation: 93

Using some prasad's information, this is my solution:

    
    public UpdateResult updateCentro(String id, JsonNode jsonNode) {
        ObjectId objectId = new ObjectId(id);
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(objectId));
        Update update = new Update();

        Iterator<Map.Entry<String, JsonNode>> fields = jsonNode.fields();
        while (fields.hasNext()) {
            Entry<String, JsonNode> field = fields.next();
            String key = field.getKey();
            JsonNode value = field.getValue();
            JsonNodeType type = value.getNodeType();
            switch (type) {
            case ARRAY:
                System.out.println(key);
                System.out.println(value);
                List<JsonNode> list = new ArrayList<JsonNode>();
                for (JsonNode arrayItem : value) {
                    list.add(arrayItem);
                }
                update.set(key, list);
                break;
            case BINARY:

                break;
            case BOOLEAN:
                update.set(key, value.asBoolean());
                break;
            case MISSING:

                break;
            case NULL:

                break;
            case NUMBER:
                update.set(key, value.asDouble());
                break;
            case OBJECT:
                update.set(key, value);
                break;
            case POJO:

                break;
            case STRING:
                update.set(key, value.asText());
                break;

            default:
                break;
            }
        }
        return mongoTemplate.updateFirst(query, update, "centros");
    }

Thanks for the help.

Upvotes: 0

prasad_
prasad_

Reputation: 14317

If the object that I give to the update method has 3 fields to be updated, in the database it leaves me those 3, but it deletes all the others.

As I have mentioned in the comments above, that is the expected behavior of the Update.fromDocument() method:

Note, that this will set attributes directly and not use $set. This means fields not given in the Document will be nulled when executing the update.

So, use this to update the specific fields:

Query query = ...;
Update update = new Update().set("key-1", "value 1").set("key-2", "value 2");
UpdateResult result = mongoTemplate.updateFirst(query, update, Document.class, "collection_name");

Note the Document is of type org.bson.Document.

Upvotes: 3

Related Questions