在一个老项目中,我们正在尝试从basicspring迁移到springboot2.3.1。为此,由于我们有一个mongo数据库,我们必须从spring数据进行迁移-mongodb:1.10.18 where 这段代码是这样写的:
DBCollection contextCollection = this.mongoTemplate.getCollection("productStock");
BulkWriteOperation builder = contextCollection.initializeUnorderedBulkOperation();
StockType stockItem = stockMessage.getStockItem();
final BasicDBObject id = new BasicDBObject("storeID", stockItem.getStoreID()).append("productID", stockItem.getProductID());
BulkWriteRequestBuilder bulkWriteRequestBuilder = builder.find(new BasicDBObject("_id", id));
HashMap<String, Object> stock = new HashMap<>();
Date currentDate = Calendar.getInstance().getTime();
stock.put("value", stockItem.getValue());
if (stockItem.getAssociateDate() != null) {
stock.put("associateDate", stockItem.getAssociateDate());
}
if (stockItem.getLastAccessDateSource() != null) {
stock.put("lastAccessDateSource", stockItem.getLastAccessDateSource());
// check
BasicDBObject ltLast = new BasicDBObject("$lt", stockItem.getLastAccessDateSource());
BasicDBList dbList = new BasicDBList();
dbList.add(new BasicDBObject(stockItem.getStockCategory() + ".lastAccessDateSource", ltLast));
dbList.add(new BasicDBObject(stockItem.getStockCategory() + ".lastAccessDateSource", null));
bulkWriteRequestBuilder = builder.find(new BasicDBObject("_id", id).append("$or", dbList));
} else {
stock.put("lastAccessDateSource", currentDate);
}
stock.put("lastUpdateDate", currentDate);
BasicDBObject set = new BasicDBObject(stockItem.getStockCategory(), new Document(stock));
bulkWriteRequestBuilder.upsert().updateOne(new BasicDBObject("$set", set));
builder.execute();
到Spring Data -mongodb:3.0.1.release with 此更新的代码
Map<String, List<StockType>> mapMultiUpdate = new HashMap<>();
StockType stockItem = stockMessage.getStockItem();
final Document id = new Document("storeID", stockItem.getStoreID()).append("productID", stockItem.getProductID());
HashMap<String, Object> stock = new HashMap<>();
Date currentDate = Calendar.getInstance().getTime();
Document searchQuery = new Document("_id", id).append("$or", dbList);
stock.put("value", stockItem.getValue());
if (stockItem.getAssociateDate() != null) {
stock.put("associateDate", stockItem.getAssociateDate());
}
if (stockItem.getLastAccessDateSource() != null) {
stock.put("lastAccessDateSource", stockItem.getLastAccessDateSource());
// check
Document ltLast = new Document("$lt", stockItem.getLastAccessDateSource());
List<Document> dbList = Lists.newArrayList();
dbList.add(new Document(stockItem.getStockCategory() + ".lastAccessDateSource", ltLast));
dbList.add(new Document(stockItem.getStockCategory() + ".lastAccessDateSource", null));
} else {
stock.put("lastAccessDateSource", currentDate);
}
//Bulk write options
BulkWriteOptions bulkWriteOptions = new BulkWriteOptions();
bulkWriteOptions.ordered(false);
bulkWriteOptions.bypassDocumentValidation(true);
MongoCollection<Document> mongoCollection = this.mongoTemplate.getCollection("productStoreStock");
mongoCollection.bulkWrite(updateDocuments, bulkWriteOptions);
但是当新代码在已经存在的对象上执行时,我们会得到一个重复的键错误
com.mongodb.MongoBulkWriteException: Bulk write operation error on server localhost:27017. Write errors: [BulkWriteError{index=0, code=11000, message='E11000 duplicate key error collection: test.productStoreStock index: _id_ dup key: { : { storeID: 400, productID: 100000 } }', details={}}].
我们也从mongo-java转换过来了-driver:3.6.4 to mongodb驱动程序-sync:4.0.4
编辑:
在测试阶段的第3步中,在空数据库/集合上引发此错误。步骤如下:
在特定日期用一种产品的库存开始收集
检查基值
在java中修改股票的值,但不修改日期并尝试更新它
由于mongo查询上的lt过滤器,检查值仍然是第一个
我们从来没有达到检查值,在迁移之前,这个测试一切正常
2条答案
按热度按时间szqfcxe21#
看起来您正在用自己的“构造”id替换内部id字段。这不是一件好事。让mongo创建它自己的\u id,它们在不同的用法中保证是唯一的。。永远不会复制。将自己的companyid作为附加字段没有错,但是替换mongodbs自动生成的id字段是危险的。。。你已经发现了。
falq053o2#
mongo没有更新,当找不到匹配项时,它正在升级(插入新行)。