1

ツアーのリストを含むモデルバンドがあります。

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

ツアーは次のとおりです。

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

目標は、バンド名を受け取るエンドポイントを作成し、ツアー名がこの入力に基づいてツアーを削除することです。

以下の作品:

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

さて、私は一日中ほぼ同じ問題に取り組んできました。私が持っているものは素晴らしいものではありませんが、喜んで受け入れるには十分であり、誰かがそれをより完全な解決策にできることを願っています. または、少なくとも他の誰かの時間を節約できます。

pullByFilter1 つの引数のみを受け入れます。引数は、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 に答える