Spring数据mongodb查询自动将String转换为ObjectId
标题可能不是很清楚,这里是问题所在
我正在以这种forms执行更新:
db.poi.update({ _id: ObjectId("50f40cd052187a491707053b"), "votes.userid": { "$ne": "50f5460d5218fe9d1e2c7b4f" } }, { $push: { votes: { "userid": "50f5460d5218fe9d1e2c7b4f", "value": 1 } }, $inc: { "score":1 } })
仅在没有具有相同用户标识的文档时才在文档中插入文档(解决方法,因为唯一索引不适用于数组)。 代码在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的String,这可以正常工作,但如果我在示例中使用该字符串,则执行的查询会像这样翻译(来自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使用ObjectId而不是String。
有什么想法吗?
更新:
这是投票类
public class Vote { private String userid; private int value; }
这是User类
@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 Setvotes = new HashSet(); }
作为杰森
{ "_id" : ObjectId("50f40cd052187a491707053b"), "name" : "Test", "score" : 12, "votes" : [ { "userid" : "50f5460d5218fe9d1e2c7b4f", "value" : 1 } ] }
将votes.userid中的Userid推送为String,但将相同的String作为$ ne中的ObjectId进行比较
在我看来,问题可以这样描述:如果你在类中使用String代替ObjectId,如果你想在其他文档(和嵌入文档)中使用这些id作为引用(没有dbrefs),它们会被推送as String(没关系,因为它们是字符串)。 这很好,因为spring数据可以将它们再次映射到objectid,但是如果你像我提到的那样进行查询则不行; 该字段在比较中转换为objectid(在本例中为$ ne运算符),但在嵌入文档中被视为字符串。 因此,总结一下,在我看来,$ ne运算符在这种情况下应该将字段视为字符串。
我的解决方案是编写一个自定义转换器,将String作为objectid存储在id为引用的文档中
public class VoteWriteConverter implements Converter { @Override public DBObject convert(Vote vote) { DBObject dbo = new BasicDBObject(); dbo.put("userid", new ObjectId(vote.getUserid())); dbo.put("value", vote.getValue()); return dbo; } }
- 在java swing应用程序中自动数据绑定数据库和用户界面的最佳方法?
- JVM如何执行Try catch finally块
- 如何从Java发送SMTP消息?
- 什么是multithreading环境中的繁忙旋转?
- 为什么我的物体不会死?
- HttpServletResponse.setStatus()工作一次,再次调用时什么都不做 – 在Java 8 / Tomcat 9.0.0和Java 10 / Tomcat 9.0.8之间进行更改?
- Hibernate Validator,自定义ResourceBundleLocator和Spring
- 调整窗口大小时,Java Swing绘图消失
- 为什么我们在匿名内部类中使用final关键字?