The title might not be super clear, here the problem
I'm executing an update in this form:
db.poi.update({
_id: ObjectId("50f40cd052187a491707053b"),
"votes.userid": {
"$ne": "50f5460d5218fe9d1e2c7b4f"
}
},
{
$push: {
votes: {
"userid": "50f5460d5218fe9d1e2c7b4f",
"value": 1
}
},
$inc: { "score":1 }
})
To insert a document in an array only if there isn't one with the same userid (workaround because unique indexes don't work on arrays). The code works fine from mongo console. From my application I'm using this:
@Override
public void vote(String id, Vote vote) {
Query query = new Query(Criteria.where("_id").is(id).and("votes.userid").ne(vote.getUserid()));
Update update = new Update().inc("score", vote.getValue()).push("votes", vote);
mongoOperations.updateFirst(query, update, Poi.class);
}
This works fine if as "userid" I use a String that can't be a mongo ObjectId, but if I use the string in the example, the query executed translates like this (from mongosniff):
update flags:0 q:{ _id: ObjectId('50f40cd052187a491707053b'), votes.userid: { $ne: ObjectId('50f5460d5218fe9d1e2c7b4f') } } o:{ $inc: { score: 1 }, $push: { votes: { userid: "50f5460d5218fe9d1e2c7b4f", value: 1 } } }
The string is now an Objectid. Is this a bug? BasicQuery do the same thing. The only other solution I see is to use ObjectId instead of String for all classes ids.
Any thoughts?
UPDATE:
This is the Vote class
public class Vote {
private String userid;
private int value;
}
This is the User class
@Document
public class User {
@Id
private String id;
private String username;
}
This is the class and mongo document where I'm doing this update
@Document
public class MyClass {
@Id
private String id;
@Indexed
private String name;
int score
private Set<Vote>votes = new HashSet<Vote>();
}
As Json
{
"_id" : ObjectId("50f40cd052187a491707053b"),
"name" : "Test",
"score" : 12,
"votes" : [
{
"userid" : "50f5460d5218fe9d1e2c7b4f",
"value" : 1
}
]
}
Userid in votes.userid is pushed as String, but the same String is compared as an ObjectId in the $ne