【发布时间】:2012-05-06 15:03:58
【问题描述】:
我正在开发一个客户数据加载器,客户可以在其中拥有多个地址。如果找不到客户,我创建它并添加地址。如果客户存在,我只需添加新地址,如下所示:
DBObject findCustomer = new BasicDBObject();
findCustomer.put("email", custEmail);
//check for existing customer
DBObject newCustomer = customerCollection.findOne(findCustomer);
if (newCustomer == null) {
//INSERT
newCustomer = new BasicDBObject();
newCustomer.put("firstname", firstname);
newCustomer.put("lastname", lastname);
newCustomer.put("email", custEmail);
newCustomer.put("password", custData.getPassword());
newCustomer.put("softwaretime", new Date());
}
DBObject newAddress = new BasicDBObject();
City tempCity = new City();
tempCity = addressData.getCity();
newAddress.put("type", addressData.getType());
newAddress.put("line1", addressData.getLine1());
newAddress.put("line2", addressData.getLine2());
newAddress.put("city", tempCity.getCity());
newAddress.put("state", tempCity.getState());
newAddress.put("postal", tempCity.getZip());
newAddress.put("country", tempCity.getCountry());
newCustomer.put("address", newAddress);
customerCollection.save(newCustomer);
这适用于新客户。问题是当客户已经存在时,新地址会覆盖现有地址。
如何将新地址添加给客户,使其保留多个地址?
根据我的发现,我应该能够通过外壳通过“推送”来完成此操作。但我不认为“推”是 BasicDBObject 上的方法。
【问题讨论】:
-
这看起来很危险 - 当您有多个客户的名字和姓氏相同时会发生什么?这段代码也不是线程安全的——如果两个线程试图创建同一个客户,你最终可能会得到一个重复。您也可能将同一个地址推送了两次。
-
好点@AsyaKamsky,我将使用电子邮件地址作为搜索键。此外,这是一个单线程应用程序,旨在将数据加载到 MongoDB 中。如果多个(竞争)线程是可能的,你会如何考虑线程安全?
-
有多种方法可以做到这一点 - 取决于您的应用程序逻辑期望/需要什么。您可以只使电子邮件唯一,然后第二次插入尝试将失败,但您的应用程序需要期待并恢复。您可以使用 Java 并发,但如果它只是地址的多个副本,那么您可以使用 $addToSet 而不是 $push,这样您就不会添加一个已经在列表中的地址。
标签: java mongodb mongodb-java