1
Datastore ds = datastore;
Query<Document> query = ds.createQuery(Document.class).field("_id").equal(documentId);
UpdateOperations<Document> ops = ds.createUpdateOperations(Document.class).set("draft.languages", draft);
        ds.update(query, ops);

this is the class i'm trying to change

@Embedded("language")
   private String language;
   private String body;

json before:

                "languages" : [
                    {
                            "language" : "en",
                            "body" : "bla blaaaaaaaaaaaa ttttttt"
                    },
                    {
                            "language" : "ru",
                            "body" : "faksdfsdghfhshsssssssssh"
                    }
            ]

json after:

                "languages" : [
                    {
                            "language" : "en",
                            "body" : "bla blaaaaaaaaaaaa ttttttt"
                    },
                    {
                            "language" : "ru",
                            "body" : "faksdfsdghfhshsssssssssh"
                    },
                    {
                            "language" : "en",
                            "body" : "blablablablalblalaakfslkdfjkldf"
                    }
            ]

draft is list of languages

i'm trying to do an update if the language exists in the draft segmant, or insert new one, the problem is the body is different so it always inserts new one instead of replacing the old one. i think i'm missing something(i used $addtoset and it added the list instead of replacing)

for now i'm using set and replacing the whole list, is there a better option?

thanks for your help!

example for what i'm trying to do

json before

insert

                    "languages" : [
                    {
                            "language" : "en",
                            "body" : "bla blaaaaaaaaaaaa"
                    },
                    {
                            "language" : "it",
                            "body" : "faksdfsdghfhshsssssssssh"
                    }
            ]

i expect the result will be:

                    "languages" : [
                    {
                            "language" : "en",
                            "body" : "bla blaaaaaaaaaaaa"
                    },
                    {
                            "language" : "ru",
                            "body" : "faksdfsdghfhshsssssssssh"
                    },
                    {
                            "language" : "it",
                            "body" : "faksdfsdghfhshsssssssssh"
                    }
            ]
roeygol
  • 4,908
  • 9
  • 51
  • 88
Itzik Lavon
  • 39
  • 1
  • 4

1 Answers1

-1

You could create a unique index for languages.language and then first try to update it, if no documents were matched you push the new document to the array

long matchedCount = coll.updateOne(
  Filters.and(
    Filters.eq("_id", new ObjectId("yourid")), 
    Filters.eq("languages.language", "en")
  ), 
  new Document(
    "$set", 
    new Document("languages.$.body", "zuzuzu"))
  ).getMatchedCount();

if (matchedCount == 0) {            
  coll.updateOne(
    Filters.eq("_id", new ObjectId("yourid")),
    new Document(
      "$push", 
      new Document(
        "languages", 
        new Document("language", "en").append("body", "zuzuzu")
      )
    )
  );
}
anders
  • 814
  • 7
  • 12
  • this works if the the list i'm trying to insert contains only 1 object..... i'm trying to put an entire list into the document...there is an example above – Itzik Lavon Dec 07 '16 at 07:09
  • loop over the list you're trying to insert – anders Dec 07 '16 at 09:40
  • thought of doing so, but i was thinking that maybe there is already a command that does it, like $addToSet that works with objects – Itzik Lavon Dec 07 '16 at 10:01