我在使用Scala中的Mongo正确地添加到嵌套数组时遇到了一些麻烦。我已经在Node.js中多次执行了相同的操作,但是由于某种原因我无法将其转换为Scala。
这是主要的“模式”:
case class Band(
_id: ObjectId,
name: String,
username: String,
email: String,
path: String,
tours: List[Tour],
merchSets: List[MerchSet],
facebook: Option[String],
twitter: Option[String],
youtube: Option[String],
instagram: Option[String],
website: Option[String]
)
object Band {
def apply(
_id: ObjectId,
name: String,
username: String,
email: String,
path: String,
tours: List[Tour],
merchSets: List[MerchSet],
facebook: Option[String],
twitter: Option[String],
youtube: Option[String],
instagram: Option[String],
website: Option[String]
): Band = new Band(_id,
name, username, email, path, tours, merchSets, facebook, twitter,
youtube, instagram, website)
val bandCodecRegistry: CodecRegistry =
fromRegistries(fromProviders(classOf[Band]), DEFAULT_CODEC_REGISTRY)
}
如您所见,该定义具有 游览列表 ,其中 游览 定义为:< / p>
case class Tour(_id: ObjectId,
name: String,
shows: List[Show],
items: List[Item],
region: String,
default_merchset : Option[MerchSet]
)
object Tour{
def apply(_id: ObjectId,
name: String,
shows: List[Show],
items: List[Item],
region: String,
default_merchset: Option[MerchSet]
): Tour = new Tour(_id, name, shows, items, region, default_merchset)
val tourCodecRegistry : CodecRegistry =
fromRegistries(fromProviders(classOf[Tour]), DEFAULT_CODEC_REGISTRY)
}
每当创建新项目时,我都尝试将某个项目推到项目集合中(如果该项目不存在)。
基本上,端点会收到一个乐队ID ,一个旅游名称和一堆用于创建和推送项目的表单参数。
目标:查询需要从相应的游览集合中找到正确的乐队和正确的游览,并将创建的项目添加到相应的游览中。
我在Node.js中执行此操作的方式如下:
var query = {"_id": id, "tours.name": name}
Band.findOneAndUpdate(
query,
{$push: {"tours.$.items": item}}
)
但这在Scala中不起作用。而且我完全没有错误。尽管数据库中没有任何更改,但订阅达到了OnComplete的情况。在OnNext案件中不会受到打击。查询以某种方式成功完成,没有错误,也没有成功...
这是我目前拥有的:
val add = MongoDataBaseConnector.bands.findOneAndUpdate(and(equal("_id", id),
equal("tours.name", tour_name)),
push("tours.items", request.toDomain))
我试图在中间使用$运算符并使用addToSet,但是它们没有任何区别。
执行此操作的正确方法是什么?
注意:这是官方的scala驱动程序,不是casbah。如何在卡斯巴(casbah)做到这一点已被无数次回答。
答案 0 :(得分:0)
结果我忘了将id强制转换为ObjectId ... 下面的查询有效
def addTourSpecificMerch(request: NewItemRequest, id: ObjectId, name: String): Unit = {
val tour_name = name.replace("%20", " ")
val add = MongoDataBaseConnector.bands.findOneAndUpdate(and(equal("_id", id),
equal("tours.name", tour_name)),
addToSet("tours.$.items", request.toDomain))
add.subscribe(new Observer[Band] {
override def onNext(result: Band): Unit = println(s"onNext: $result")
override def onError(e: Throwable): Unit = println(s"onError: $e")
override def onComplete(): Unit = println("onComplete")
})
}