タイトルはあまり明確ではないかもしれません、ここに問題があります
次の形式で更新を実行しています。
db.poi.update({
_id: ObjectId("50f40cd052187a491707053b"),
"votes.userid": {
"$ne": "50f5460d5218fe9d1e2c7b4f"
}
},
{
$push: {
votes: {
"userid": "50f5460d5218fe9d1e2c7b4f",
"value": 1
}
},
$inc: { "score":1 }
})
同じユーザー ID を持つドキュメントがない場合にのみ配列にドキュメントを挿入するには (一意のインデックスが配列では機能しないための回避策)。コードは mongo コンソールから正常に動作します。私のアプリケーションから、私はこれを使用しています:
@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);
}
これは、「userid」として mongo ObjectId にできない文字列を使用する場合は正常に機能しますが、例で文字列を使用すると、実行されたクエリは次のように変換されます (mongosniff から):
update flags:0 q:{ _id: ObjectId('50f40cd052187a491707053b'), votes.userid: { $ne: ObjectId('50f5460d5218fe9d1e2c7b4f') } } o:{ $inc: { score: 1 }, $push: { votes: { userid: "50f5460d5218fe9d1e2c7b4f", value: 1 } } }
文字列は Objectid になりました。これはバグですか?BasicQuery も同じことを行います。私が見る他の唯一の解決策は、すべてのクラス ID に String の代わりに ObjectId を使用することです。
何かご意見は?
アップデート:
これは投票クラスです
public class Vote {
private String userid;
private int value;
}
これはユーザークラスです
@Document
public class User {
@Id
private String id;
private String username;
}
これは、この更新を行っているクラスと mongo ドキュメントです。
@Document
public class MyClass {
@Id
private String id;
@Indexed
private String name;
int score
private Set<Vote>votes = new HashSet<Vote>();
}
Jsonとして
{
"_id" : ObjectId("50f40cd052187a491707053b"),
"name" : "Test",
"score" : 12,
"votes" : [
{
"userid" : "50f5460d5218fe9d1e2c7b4f",
"value" : 1
}
]
}
votes.userid のユーザー ID は文字列としてプッシュされますが、同じ文字列が $ne の ObjectId として比較されます。