繁体   English   中英

MongoDB:如果不存在则插入记录,如果存在则忽略

[英]MongoDB: insert record if it doesn't exist, ignore if it does

我有一系列MongoDB记录,如:

{"name":"Bob", "gpa":4} {"name":"Sarah", "gpa":3}

我会遇到可能会或可能不会属于同一个人的各种其他记录。 如果他们是新人,我想接受他们,如果他们是我们以前见过的人,就不要更新他们。 所以,如果我得到{"name":"Jim", "gpa":2} ,我想接受原样。 如果我得到{"name":"Sarah", "gpa":4} (不同的GPA值),我想忽略它。 这似乎不是将“upsert”设置为yes或使用“upsert”的findAndModify进行update的逻辑。

https://stackoverflow.com/a/3260290/514757建议一种方式(第一个字段上的唯一索引,插入记录,立即更新第二个字段)但它已经有几年了,我想知道是否有更好的方法现在只需一步即可完成此操作。

编辑:

接受的答案看起来很棒,但它对我不起作用! 首先,我创建了索引(这是使用Java驱动程序):

nameIndex.put("name", 1);
nameIndex.put("unique", true);
queue.ensureIndex(nameIndex);

我可以从命令行看到索引存在且是唯一的。 然后,插入一个项目:

DBObject person = new BasicDBObject();
person.put("name", "Bob");
person.put("score", 200000);
queue.insert(person);

之后,得分最高的项目的分数降至零:

BasicDBObject reset = new BasicDBObject();
reset.put("$set", new BasicDBObject("score", 0));
DBObject dbObj = queue.findAndModify(null, new BasicDBObject("score", -1), reset);

所有这些都按预期工作! 但是,稍后,可能会再次找到相同的名称,并带有新的分数。 当最后一段代码运行时,会创建一个具有不同分数的新项目,这正是我不想要的:

BasicDBObject queueable = new BasicDBObject();
queueable.put("name", "Could be Bob again, could be someone new");
queueable.put("score", 1234);
queue.insert(queueable);

如果我搜索Bob,我会发现:

{ "_id" : ObjectId("4f5e865ad6d09315326ea0f0"), "score" : 0, "name" : "Bob" }
{ "_id" : ObjectId("4f5e8691d6d09315326ea190"), "name" : "Bob", "score" : 886 }

已创建第二条记录,再次获得更高分。 字段的顺序是否重要? 它似乎不应该,我不知道如何控制它。

完成此操作的最佳方法是使用以下命令在名称字段上设置唯一索引:

db.foo.ensureIndex({name:1}, {unique:true});

这会导致Sarah在进行插入调用时不会更新,因为它会找到另一条记录,其中已经为名称字段设置了“Sarah”。

您的ensureIndex()调用不太正确。 ensureIndex()的第一个参数包含应编入索引的键; 索引选项(如唯一性)可以作为第二个参数传递。 请参阅Java驱动程序文档

你现在所拥有的是尝试在两个字段上创建一个非唯一索引:“name”和“unique”。

试试这个来创建你的索引:

DBObject nameIndex = new BasicDBObject();
nameIndex.put("name",1);

DBObject nameIndexOptions = new BasicDBObject();
nameIndexOptions.put("unique", true);

queue.ensureIndex(nameIndex, nameIndexOptions);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM