1

我有一个模型乐队,其中包含旅行列表

Band:
{ 
  name: String,
  email: String,
  createdAt: String,
  tours: Tour[],
  ...
}

旅游在哪里:

{
name: String,
region: String,
published: Boolean,
...
}

目标只是创建一个接收 Band Name 的端点,Tour Name 会根据此输入删除巡演。

以下作品:

bandService.getBandByName(req.getParam("bandName")).flatMap{ b =>
  val tour = b.tours.filter(t => t.name == req.getParam("tourName")).head
  mongoDataBaseConnector.bands.findOneAndUpdate(
    equal("bandName", req.getParam("bandName")),
    pull("tours", tour)
  ).toFuture().flatMap(u => bandService.getBandByName(req.getParam("bandName")))

但是,这需要我首先通过首先收到的名称解析乐队,过滤,找到游览并将确切的对象传递给我试图通过使用pullByFilter来避免这种情况,但似乎无法让它工作. 不幸的是,在 scala 驱动程序中找不到此函数的任何示例。

这就是我正在尝试的:

mongoDataBaseConnector.bands.findOneAndUpdate(
      and(
        equal("bandName", req.getParam("bandName")),
        equal("tours.name", req.getParam("tourName"))),
      pullByFilter(and(
        equal("tours.$.name", req.getParam("tourName")),
        equal("tours.$.region", req.getParam("region"))
      ))
    ).toFuture().flatMap(u => bandService.getBandByName(req.getParam("bandName")))

这给出了以下错误:

com.mongodb.MongoCommandException: Command failed with error 2 (BadValue): 'Cannot apply $pull to a non-array value' on server cluster0-shard-00-01-sqs4t.mongodb.net:27017. The full response is {"operationTime": {"$timestamp": {"t": 1568589476, "i": 8}}, "ok": 0.0, "errmsg": "Cannot apply $pull to a non-array value", "code": 2, "codeName": "BadValue", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1568589476, "i": 8}}, "signature": {"hash": {"$binary": "Qz/DqAdG11H8KRkW8gtvRAAE61Q=", "$type": "00"}, "keyId": {"$numberLong": "6710077417139994625"}}}}

任何想法表示赞赏。这个功能甚至可以实现吗?

4

1 回答 1

0

好的,我整天都在研究一个几乎相同的问题。我所拥有的不是很好,但足以让我愿意接受它,并希望有人能够将其变成一个更完整的解决方案。或者至少我可以为别人节省一些时间。

pullByFilter只接受一个论点。似乎参数可以Bson是直接应用于每个孩子的另一个过滤器,或者是一个BsonValue将被匹配的过滤器。由于没有Bson过滤器进入子文档,因此您必须创建一个BsonValue,特别是一个文档。我相信这应该可以解决您的问题:

mongoDataBaseConnector.bands.findOneAndUpdate(
      and(
        equal("bandName", req.getParam("bandName")),
        equal("tours.name", req.getParam("tourName"))),
      pullByFilter(BsonDocument().append("tours", BsonDocument()
          .append("name", req.getParam("tourName"))
          .append("region", req.getParam("region"))
      ))
    ).toFuture().flatMap(u => bandService.getBandByName(req.getParam("bandName")))

我本来希望能够Bson在进入内部文档后使用过滤器切换回来,但似乎一旦进入BsonValues,就无法返回。

编辑:帮助追随我的人:我认为应该有一种方法可以更干净地解决这个问题arrayFilters,但我还没有找到它。

于 2021-01-18T03:10:59.873 回答