如何在JMeter插入MongoDB文档时使用服务端时间戳而非客户端时间戳
问题根因
Updates.currentDate() 是MongoDB专属的更新操作算子,仅可用于updateOne()、updateMany()等更新方法,不能直接作为普通字段值传入insertOne()的文档对象中,你之前的写法会把$currentDate的结构当成普通字段值存入数据库,不会触发服务端时间生成逻辑。
注:如果你的JMeter使用的是Groovy脚本引擎,原来的
for(int i in 0..99)循环写法可以保留,无需修改为下文的Java标准for循环。
解决方案1:使用Upsert更新操作(兼容所有MongoDB版本)
将插入逻辑替换为空查询+ upsert = true的更新操作,直接用更新算子插入全量字段和服务端时间,首先新增两个导入包:
import com.mongodb.client.model.Filters; import com.mongodb.client.model.UpdateOptions;
修改后完整代码:
import com.mongodb.client.MongoCollection; import org.bson.Document; import java.util.Arrays; import java.util.Date; import java.sql.Timestamp; import com.mongodb.client.model.Updates; import com.mongodb.client.model.Filters; import com.mongodb.client.model.UpdateOptions; try { MongoCollection<Document> collection = vars.getObject("collection"); ArrayList items = new ArrayList<Document>(); Date date= new Date(); long time = date.getTime(); Timestamp ts = new Timestamp(time); for(int i = 0; i < 100; i++){ Document item = new Document("_id",i) .append("category","calibration") .append("instanceId","string1") .append("alertCode",0) .append("code","string5") .append("JmeterClientCurrentDate", time); items.add(item); } // 用upsert实现插入+服务端时间生成 collection.updateOne( // 匹配一个不存在的过滤条件,确保触发插入逻辑 Filters.eq("_id", "non_exist_placeholder"), Arrays.asList( Updates.set("deviceId","${deviceId}"), Updates.currentDate("documentInsertTime"), Updates.set("shadowName","alerts"), Updates.set("shadowDocument",new Document("state",new Document("reported",new Document("cdmData",new Document("items",items))))), Updates.set("_class","com.hp.stratus.iotmesh.mongodb.DeviceShadow") ), // 开启upsert,匹配不到文档时执行插入 new UpdateOptions().upsert(true) ); return "Document inserted"; } catch (Exception e) { SampleResult.setSuccessful(false); SampleResult.setResponseCode("500"); SampleResult.setResponseMessage("Exception: " + e); }
解决方案2:使用聚合管道插入(适配MongoDB 4.2及以上版本)
如果你的MongoDB服务端版本≥4.2,可以直接用内置变量$$NOW在插入时生成服务端时间,代码更简洁,修改后完整代码:
import com.mongodb.client.MongoCollection; import org.bson.Document; import java.util.Arrays; import java.util.Date; import java.sql.Timestamp; import com.mongodb.client.model.Updates; try { MongoCollection<Document> collection = vars.getObject("collection"); ArrayList items = new ArrayList<Document>(); Date date= new Date(); long time = date.getTime(); Timestamp ts = new Timestamp(time); for(int i = 0; i < 100; i++){ Document item = new Document("_id",i) .append("category","calibration") .append("instanceId","string1") .append("alertCode",0) .append("code","string5") .append("JmeterClientCurrentDate", time); items.add(item); } // 用聚合管道构造文档,$$NOW为MongoDB服务端当前时间变量 collection.insertOne( new Document("$set", new Document("deviceId","${deviceId}") .append("documentInsertTime", "$$NOW") .append("shadowName","alerts") .append("shadowDocument",new Document("state",new Document("reported",new Document("cdmData",new Document("items",items))))) .append("_class","com.hp.stratus.iotmesh.mongodb.DeviceShadow") ) ); return "Document inserted"; } catch (Exception e) { SampleResult.setSuccessful(false); SampleResult.setResponseCode("500"); SampleResult.setResponseMessage("Exception: " + e); }
内容的提问来源于stack exchange,提问作者Surya Chandra
相关产品推荐
相关产品推荐

