【问题标题】:Unrecognized pipeline stage name: '$setOnInsert'无法识别的管道阶段名称:'$setOnInsert'
【发布时间】:2021-02-10 01:48:49
【问题描述】:

使用版本 4.4.1 中的独立 MongoDB 实例和使用最新驱动程序 (org.mongodb:mongodb-driver-sync:4.1.1) 连接的 Java 客户端,当使用 调用 findOneAndUpdate 时出现错误>$setOnInsert 运算符。

这是使用的查询:

final List<Bson> updates = new ArrayList<>();
updates.add(Updates.set("data", "test"));
updates.add(Updates.setOnInsert("firstSeenTime", new Date()));

final Document updatedDocument =
    this.visitorsCollection.findOneAndUpdate(
        eq("userId", "u1"), updates, new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER).upsert(true));

错误:

线程“主”com.mongodb.MongoCommandException 中的异常:命令 失败并出现错误 40324 (Location40324):'无法识别的管道阶段 名称:服务器 A.B.C.D:XXXXX 上的“$setOnInsert”。完整的 响应是 {"ok": 0.0, "errmsg": "无法识别的管道阶段名称: '$setOnInsert'", "code": 40324, "codeName": "Location40324"} 在 com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:175) 在 com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:359) 在 com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:280) 在 com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:100) 在 com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:490) 在 com.mongodb.internal.connection.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) 在 com.mongodb.internal.operation.CommandOperationHelper$13.call(CommandOperationHelper.java:712) 在 com.mongodb.internal.operation.OperationHelper.withReleasableConnection(OperationHelper.java:620) 在 com.mongodb.internal.operation.CommandOperationHelper.executeRetryableCommand(CommandOperationHelper.java:705) 在 com.mongodb.internal.operation.CommandOperationHelper.executeRetryableCommand(CommandOperationHelper.java:697) 在 com.mongodb.internal.operation.BaseFindAndModifyOperation.execute(BaseFindAndModifyOperation.java:69) 在 com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:195) 在 com.mongodb.client.internal.MongoCollectionImpl.executeFindOneAndUpdate(MongoCollectionImpl.java:785) 在 com.mongodb.client.internal.MongoCollectionImpl.findOneAndUpdate(MongoCollectionImpl.java:765)

如果我摆脱了Updates.setOnInsert(...) 调用,那么更新会起作用,但不是我想要的。我的目的是根据要更新的文档是否存在来设置一些字段。查看文档,应该支持 $setOnInsert

https://docs.mongodb.com/manual/reference/operator/update/#id1

知道哪里出了问题吗?

【问题讨论】:

  • 我可能会被误导,但如果错误Unrecognized pipeline stage name 真的意味着艺名,那么$setOnInsert 不作为艺名存在,但$set 确实存在。
  • 感谢您的帮助,但如果您查看链接(来自官方文档),我输入了我的问题描述,您会看到 $setOnInsert 是一个有效的更新运算符。

标签: java mongodb mongodb-query


【解决方案1】:

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

  • 包含更新运算符表达式的文档
  • 包含$set$unset$replaceRoot 聚合阶段的数组

由于您将 updates 创建为 ArrayList,因此 findOneAndUpdate 尝试将其作为聚合管道处理,该管道无法识别 $setOneInsert 阶段。

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

【讨论】:

    猜你喜欢
    • 2019-09-01
    • 2020-10-07
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    相关资源
    最近更新 更多