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

如何使用Mongo驱动将JS的updateMany迁移至Scala?

问题描述

我有一段可正常运行的MongoDB JS查询,作用是将$_id字段的值转为字符串后设置为idempotencyKey字段:

db.getCollection('my_collection')
.updateMany({},
[{ $set: { idempotencyKey: { $convert: { input: "$_id", to: "string" } } } }]
)

我尝试将其迁移到Scala代码,但未达到预期效果:

val setDefaultIdempotencyKeyExpression =
  """{ $set: { idempotencyKey: { $convert: { input: "$_id", to: "string" } } } }""".stripMargin

getCollection("my_collection").updateMany(
  Filters.not(Filters.exists("idempotencyKey")),
  Document(setDefaultIdempotencyKeyExpression)
).toFuture()
  .map(_.getModifiedCount)

我不清楚如何用Scala DSL表达该JS查询,于是尝试传递原始JSON到Document,但代码直接把{"$convert": {"input": "$_id", "to": "string"}}作为字符串值赋值给了idempotencyKey,而非执行转换逻辑。另外,我无法像JS查询那样传递数组形式的更新语句,因为Document仅接受JSON对象,不支持数组格式。

请问正确的实现方式是什么?


解决方案

方法1:用Scala MongoDB DSL构建聚合管道式更新

你原来的JS查询用的是聚合管道式更新(数组形式的更新语句),Scala驱动里可以通过Aggregates工具类构建对应的管道阶段,再用Updates.pipeline()包裹这些阶段:

import org.mongodb.scala.model._

// 构建$set聚合阶段,包含$convert转换逻辑
val setIdempotencyKey = Aggregates.set(
  "idempotencyKey",
  Aggregates.convert(
    Field("_id"),
    ConvertOptions().to(ConvertType.STRING)
  )
)

// 执行更新:用Updates.pipeline包裹聚合阶段数组
getCollection("my_collection").updateMany(
  Filters.not(Filters.exists("idempotencyKey")),
  Updates.pipeline(setIdempotencyKey)
).toFuture()
  .map(_.getModifiedCount)

方法2:直接用BsonArray传递原始管道数组

如果更习惯写原始JSON,可以用BsonArray来包裹更新管道(而非Document):

import org.bson.BsonArray
import org.bson.Document

val pipeline = BsonArray.parse("""
  [{ $set: { idempotencyKey: { $convert: { input: "$_id", to: "string" } } } }]
""")

getCollection("my_collection").updateMany(
  Filters.not(Filters.exists("idempotencyKey")),
  pipeline
).toFuture()
  .map(_.getModifiedCount)

原代码失效原因

你之前用Document传递单个$set对象时,MongoDB会将其识别为普通更新文档,而非聚合管道。此时$convert不会被解析为操作符,而是直接作为字符串值存入字段,这就是问题的核心。只有用数组形式的聚合管道,MongoDB才会执行其中的表达式逻辑。

内容的提问来源于stack exchange,提问作者Capacytron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:42:09