ale*_*lex 6 java mongodb spring-data
标题可能不是很清楚,这里是问题
我正在以这种形式执行更新:
db.poi.update({
_id: ObjectId("50f40cd052187a491707053b"),
"votes.userid": {
"$ne": "50f5460d5218fe9d1e2c7b4f"
}
},
{
$push: {
votes: {
"userid": "50f5460d5218fe9d1e2c7b4f",
"value": 1
}
},
$inc: { "score":1 }
})
Run Code Online (Sandbox Code Playgroud)
仅当没有具有相同用户 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);
}
Run Code Online (Sandbox Code Playgroud)
如果作为“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 } } }
Run Code Online (Sandbox Code Playgroud)
该字符串现在是一个 Objectid。这是一个错误吗?BasicQuery 做同样的事情。我看到的唯一其他解决方案是对所有类 ID 使用 ObjectId 而不是 String。
有什么想法吗?
更新:
这是投票类
public class Vote {
private String userid;
private int value;
}
Run Code Online (Sandbox Code Playgroud)
这是用户类
@Document
public class User {
@Id
private String id;
private String username;
}
Run Code Online (Sandbox Code Playgroud)
这是我进行此更新的类和 mongo 文档
@Document
public class MyClass {
@Id
private String id;
@Indexed
private String name;
int score
private Set<Vote>votes = new HashSet<Vote>();
}
Run Code Online (Sandbox Code Playgroud)
作为 Json
{
"_id" : ObjectId("50f40cd052187a491707053b"),
"name" : "Test",
"score" : 12,
"votes" : [
{
"userid" : "50f5460d5218fe9d1e2c7b4f",
"value" : 1
}
]
}
Run Code Online (Sandbox Code Playgroud)
votes.userid 中的 Userid 作为 String 推送,但相同的 String 在 $ne 中作为 ObjectId 进行比较
在我看来,问题可以这样描述:如果您在类中使用 String 代替 ObjectId,如果您想在其他文档(和嵌入文档)中使用这些 id 作为引用(无 dbrefs),它们将被推送作为字符串(没关系,因为它们是字符串)。这很好,因为 spring data 可以将它们再次映射到 objectid,但是如果你执行像我提到的那样的查询,那就不好了;该字段在比较中转换为 objectid(在本例中为 $ne 运算符),但在嵌入文档中被视为字符串。因此,总而言之,我认为在这种情况下 $ne 运算符应该将该字段视为字符串。
我的解决方案是编写一个自定义转换器,将字符串作为 objectid 存储在文档中,其中 id 是引用
public class VoteWriteConverter implements Converter<Vote, DBObject> {
@Override
public DBObject convert(Vote vote) {
DBObject dbo = new BasicDBObject();
dbo.put("userid", new ObjectId(vote.getUserid()));
dbo.put("value", vote.getValue());
return dbo;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22540 次 |
| 最近记录: |