You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 23:54:04