Java 无法识别的管道阶段名称:'$setOnInsert';

Java 无法识别的管道阶段名称:'$setOnInsert';,java,mongodb,mongodb-query,Java,Mongodb,Mongodb Query,使用版本4.4.1中的独立MongoDB实例和使用最新驱动程序(org.MongoDB:MongoDB驱动程序同步:4.1.1)连接的Java客户端,我在使用$setOnInsert操作符调用findOneAndUpdate时遇到错误 以下是使用的查询: final List updates=new ArrayList(); updates.add(updates.set(“数据”、“测试”)); updates.add(updates.setOnInsert(“firstSeenTime”,n

使用版本4.4.1中的独立MongoDB实例和使用最新驱动程序(
org.MongoDB:MongoDB驱动程序同步:4.1.1
)连接的Java客户端,我在使用$setOnInsert操作符调用
findOneAndUpdate
时遇到错误

以下是使用的查询:

final List updates=new ArrayList();
updates.add(updates.set(“数据”、“测试”));
updates.add(updates.setOnInsert(“firstSeenTime”,newdate());
最终文件更新文件=
this.visitorsCollection.findOneAndUpdate(
eq(“userId”,“u1”),更新,新的FindOneAndUpdateOptions().returnDocument(returnDocument.AFTER).upsert(true));
错误:

线程“main”com.mongodb.MongoCommandException:命令中出现异常 失败,错误为40324(位置40324):“无法识别的管道阶段” 服务器A.B.C.D:XXXXX上的名称:“$setOnInsert”。全部 响应为{“确定”:0.0,“errmsg”:“无法识别的管道阶段名称: “$setOnInsert”“,“代码”:40324,“代码名”:“Location40324”}位于 com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:175) 在 com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:359) 在 com.mongodb.internal.connection.InternalStreamConnection.sendandereceive(InternalStreamConnection.java:280) 在 com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:100) 在 com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:490) 在 CommandProtocolImpl.execute(CommandProtocolImpl.java:71) 在 com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:255) 在 com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:202) 在 com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:118) 在 com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:110) 在 CommandOperationHelper$13.call(CommandOperationHelper.java:712) 在 com.mongodb.internal.operation.OperationHelper.withReleasableConnection(OperationHelper.java:620) 在 com.mongodb.internal.operation.CommandOperationHelper.ExecuteTryableCommand(CommandOperationHelper.java:705) 在 com.mongodb.internal.operation.CommandOperationHelper.ExecuteTryableCommand(CommandOperationHelper.java:697) 在 com.mongodb.internal.operation.BaseFindAndModifyOperation.execute(BaseFindAndModifyOperation.java:69) 在 mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:195) 在 mongodb.client.internal.MongoCollectionImpl.executeFindOneAndUpdate(MongoCollectionImpl.java:785) 在 mongodb.client.internal.MongoCollectionImpl.findOneAndUpdate(MongoCollectionImpl.java:765)

如果我去掉了
Updates.setOnInsert(…)
调用,那么更新工作正常,但不是我想要的。我的目的是根据要更新的文档是否存在来设置一些字段。查看文档,应支持$setOnInsert:


你知道怎么回事吗?

这里的问题是findOneAndUpdate有两种形式。第二个参数可以是:

  • 包含更新运算符表达式的文档
  • 包含
    $set
    $unset
    $replaceRoot
    聚合阶段的数组
由于您正在将
更新
创建为ArrayList,因此findOneAndUpdate尝试将其作为聚合管道进行处理,而聚合管道无法识别
$setOneInsert
阶段


您需要将
更新
构建为文档,以便识别更新运算符。按照您的示例,您可以简单地用
更新来包装列表。合并(更新)
并将其作为第二个参数传递给
findOneAndUpdate

我可能会被误导,但如果错误
无法识别的管道阶段名称
实际上是指阶段名称,然后,
$setOnInsert
不作为阶段名称存在,但是,
$set
确实存在。感谢您的帮助,但是如果您查看我在问题描述中添加的链接,您将看到,
$setOnInsert
是有效的更新运算符。