Die mongodb-Abfrage für Spring-Daten konvertiert String automatisch in ObjectId
Der Titel dürfte nicht ganz klar sein, hier das Problem
Ich führe ein Update in dieser Form durch:
db.poi.update({
_id: ObjectId("50f40cd052187a491707053b"),
"votes.userid": {
"$ne": "50f5460d5218fe9d1e2c7b4f"
}
},
{
$push: {
votes: {
"userid": "50f5460d5218fe9d1e2c7b4f",
"value": 1
}
},
$inc: { "score":1 }
})
So fügen Sie ein Dokument nur dann in ein Array ein, wenn es kein Dokument mit derselben Benutzer-ID gibt (Problemumgehung, da eindeutige Indizes für Arrays nicht funktionieren). Der Code funktioniert gut von der Mongo-Konsole. In meiner Anwendung verwende ich Folgendes:
@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);
}
Dies funktioniert einwandfrei, wenn ich als "userid" einen String verwende, der keine mongo-Objekt-ID sein kann. Wenn ich jedoch den String im Beispiel verwende, wird die ausgeführte Abfrage folgendermaßen übersetzt (von mongosniff):
update flags:0 q:{ _id: ObjectId('50f40cd052187a491707053b'), votes.userid: { $ne: ObjectId('50f5460d5218fe9d1e2c7b4f') } } o:{ $inc: { score: 1 }, $push: { votes: { userid: "50f5460d5218fe9d1e2c7b4f", value: 1 } } }
Die Zeichenfolge ist jetzt eine Objectid. Ist das ein Bug? BasicQuery macht dasselbe. Die einzige andere Lösung, die ich sehe, ist die Verwendung von ObjectId anstelle von String für alle Klassen-IDs.
Irgendwelche Gedanken?
AKTUALISIEREN:
Dies ist die Abstimmungsklasse
public class Vote {
private String userid;
private int value;
}
Dies ist die Benutzerklasse
@Document
public class User {
@Id
private String id;
private String username;
}
Dies ist das Klassen- und Mongodokument, in dem ich dieses Update durchführe
@Document
public class MyClass {
@Id
private String id;
@Indexed
private String name;
int score
private Set<Vote>votes = new HashSet<Vote>();
}
Wie Json
{
"_id" : ObjectId("50f40cd052187a491707053b"),
"name" : "Test",
"score" : 12,
"votes" : [
{
"userid" : "50f5460d5218fe9d1e2c7b4f",
"value" : 1
}
]
}
Userid in votes.userid wird als String gepusht, aber derselbe String wird mit einer ObjectId in $ ne verglichen