0

Suppose my data is like this:

([{

attribute: 'amount'
rank: 1
value: '500'
rules:
    [{
        name:'R1',
        parent: 'true',
        successor_attr: 'project',
    },

        name:'R2',
        parent: 'true',
        successor_attr: 'type',
    }]
})]

Now, in the list rules, I want to add an object if it's not present or else leave it as it is, basically an 'upsert' operation. To achieve the same, I tried:

BasicDBObject criteria = new BasicDBObject();
criteria.append("attribute", doc.getString("attribute"));
criteria.append("value", doc.getString("value"));
criteria.append("rank", doc.getInteger("rank"));
criteria.append("rules.name", list.getString("name"));
criteria.append("rules.parent", list.getString("parent"));
criteria.append("rules.successor_attr", list.getString("attribute"));

//To add the object if not present already.
BasicDBObject docdetail = new BasicDBObject();
docdetail.put("name", list.getString("name"));
docdetail.put("parent", list.getString("parent"));
docdetail.put("successor_attr", list.getString("attribute"));

BasicDBObject modifiedObject = new BasicDBObject();
modifiedObject.put("$push", new BasicDBObject().append("rules",docdetail));
collection1.update(criteria,modifiedObject,true,false);

When trying to do the same, I'm getting the error:

Write failed with error code 2 and error message 'The field 'rules' must     be an array but is of type object in document {no id}'

The error is at the last line (collection1.update...). Please suggest how can I remove this error and achieve the functionality I want.

Indranil
  • 17
  • 1
  • 7

1 Answers1

0

Your criteria for rules seems a little off, as all three attributes are set to the name fo the list.

Otherwise, if you only want to add a rule that doesn't already exist, use the addtoset operator instead of the push. This is also described in this question. Following your code sample:

BasicDBObject modifiedObject = new BasicDBObject();
modifiedObject.put("$addtoset", new BasicDBObject("rules", docdetail));
collection1.update(criteria, modifiedObject, false, false);

Please note that you don't want to upsert into the collection, only into the rules set.

Roald Bankras
  • 564
  • 4
  • 14
  • I got the point, but can you write it down how I'd have to modify this code to add a new rule(if it's absent). I'm not sure how to do it in my case. EDIT: I've corrected the mistake I made on the "criteria" part. – Indranil Sep 03 '18 at 12:11