【问题标题】:How do I avoid duplicate object entry in Mongodb?如何避免 Mongodb 中的重复对象条目?
【发布时间】:2015-09-09 15:26:06
【问题描述】:

现在在我的项目中,我使用的是 Play 框架 (JAVA) 和 Mongodb。我的收藏中有两个字段,分别是哈希和地址。请注意,地址字段是一个对象。

我的收藏是这样的:

db.hashed.find()
{ "_id" : ObjectId("55f04cd0d4c68ef1211e6ee4"), "hash" : "1axuhWcqKB", "address" : { "floor" : 0, "block" : "5", "city" : "Mumbai", "state" : "ABC", "pincode" : 0, "latitude" : "77.6876", "longitude" : "13.57558", "hash" : "1axuhWcqKB" } }
{ "_id" : ObjectId("55f04cd1d4c68ef1211e6ee6"), "hash" : "1ay4P407qF", "address" : { "floor" : 0, "block" : "5", "city" : "Mumbai", "state" : "ABC", "pincode" : 0, "latitude" : "77.6876", "longitude" : "13.57558", "hash" : "1ay4P407qF" } }
{ "_id" : ObjectId("55f04cd2d4c68ef1211e6ee8"), "hash" : "1ayDn3Zemh",    "address" : { "floor" : 0, "block" : "5", "city" : "Mumbai", "state" : "ABC", "pincode" : 0, "latitude" : "77.6876", "longitude" : "13.57558", "hash" : "1ayDn3Zemh" } } 

现在我正在考虑如何避免重复的地址条目,这显然不应该插入到数据库中。我尝试在地址字段上做 ensureindex,但看起来它不能解决这个问题。

> db.users.ensureIndex({"address" : 1},{unique: true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 2,
"note" : "all indexes already exist",
"ok" : 1
}

希望有人可以帮助我解决这个问题。

【问题讨论】:

    标签: java mongodb playframework


    【解决方案1】:

    我认为问题在于地址子对象内的“哈希”属性。它们对于所有三行都是不同的。这就是为什么 mongodb 不将它们视为重复键的原因。这是我的工作示例(虽然没有 Play 框架,但它并没有改变重点):

    import java.util.LinkedHashMap;
    import java.util.Map;
    
    import org.jongo.Jongo;
    import org.jongo.MongoCollection;
    
    import com.mongodb.DB;
    import com.mongodb.MongoClient;
    
    public class MongodbTest {
        public static void main(String[] args) throws Exception {
            String tableName = "UniqueAddressTest";
            DB mdb = new MongoClient("localhost:27017").getDB(tableName);
            Jongo jdb = new Jongo(mdb);
            MongoCollection users = jdb.getCollection(tableName);
            users.drop();
            users.ensureIndex("{address:1}", "{unique:true}");
            Map<String, Object> user1 = new LinkedHashMap<String, Object>();
            Map<String, Object> address1 = new LinkedHashMap<String, Object>();
            address1.put("floor", 0);
            address1.put("block", "5");
            address1.put("city", "Mumbai");
            address1.put("state", "ABC");
            address1.put("pincode", 0);
            address1.put("latitude", "77.6876");
            address1.put("longitude", "13.57558");
            address1.put("hash", "1axuhWcqKB");
            user1.put("address", address1);
            users.insert(user1);
            users.insert(user1); // Here is where duplicate key exception happens
        }
    }
    

    [更新]如果您需要检查除“哈希”之外的所有地址字段的唯一性,您需要将索引更改为:

        users.ensureIndex("{address.floor:1, address.block:1, address.city:1, " +
                "address.state:1, address.pincode:1, address.latitude:1, " +
                "address.longitude:1}", "{name:\"unique_address\", unique:true}");
    

    【讨论】:

    • 感谢您的回复。那么这是否意味着我将永远无法在数据库级别检查重复项,看起来我只能通过代码执行此操作?也许你可以对此发表评论:)
    • 您可以通过将索引更改为以下内容来检查重复项: users.ensureIndex("{address.floor:1, address.block:1, address.city:1, " + " address.state:1, address.pincode:1, address.latitude:1, " + "address.longitude:1}", "{name:\"unique_address\", unique:true}");
    • 您的意思是在数据库级别上是这样的吗? db.ensureIndex("{address.floor:1, address.block:1, address.city:1,"address.state:1, address.pincode:1, address.latitude:1, " "address.longitude:1 }", "{name:\"unique_address\", unique:true}")。如果我错过了什么,请告诉我。顺便说一句,再次感谢您提供的信息丰富的回答。
    • 在 mongo 命令行客户端只使用这个: db.users.ensureIndex({"address.floor":1, "address.block":1, "address.city":1, "address .state":1, "address.pincode":1, "address.latitude":1, "address.longitude":1}, {name:"unique_address", unique:true})
    猜你喜欢
    • 2012-08-24
    • 2013-10-20
    • 1970-01-01
    • 2021-12-19
    • 2023-03-22
    • 2015-07-30
    • 1970-01-01
    • 2014-06-17
    相关资源
    最近更新 更多