web-dev-qa-db-ja.com

MongoDb:外部ドキュメントのフィルタリングによる集約$ lookup

いくつかのコレクションを考えると:

1.-ユーザー

{
  name: ...
  id: ...
  city: ...
  age: ...
  otherdata: ...
}

2.-ペット

{
  name: ...
  owner: ...
  type: ...
  age: ...
}

$ lookupで集計を使用して、ユーザーとペットを表す一連のオブジェクトを作成しようとしています。

collectionusers.aggregate([
   {
     $lookup: {
       from: "pets",
       localField: "id",
       foreignField: "owner",
       as: "pets"
     }
   }
]);

しかし、1年以上前のペットのみが各ユーザーに追加されるようにフィルターを追加したいと思います(ペットオブジェクト内のフィールドageを使用)。

問題は、古いペットを持たないユーザーをフィルターで除外するため、集計に$ matchを追加しても機能せず、ペットがいなくてもユーザーがそこにいることです。

実際、私も各ユーザーの最も古いペットのみを同じ方法で取得しようとしていますが、式も見つかりませんでした。

集計内でこのアクションを実行する方法はありますか?

もちろん、現在私は後で、返されたオブジェクトに対してそれを行っています。

前もって感謝します。

15
Gabriel

$filterステージによって生成されたpets配列に対して、 $lookup 配列集約演算子を使用できます。

1年以上経過したペットを出力するには

db.users.aggregate([ 
{ 
  $lookup: 
  { 
    from: "pets", 
    localField: "id", 
    foreignField: "owner", 
    as: "pets" 
  } 
}, 
{
  $project: 
  {
    name: 1,
    pets: 
    { 
      $filter: 
      { 
        input: "$pets", 
        as: "pet", 
        cond: { $gte: [ "$$pet.age", 1 ] } 
      } 
    } 
  } 
} 
]);

最も古いペットを出力するには、前の集計パイプラインの$filter演算子のcondフィールドを

cond: { $eq: [ "$$pet.age", { $max: "$pets.age" } ] }
15
tarashypka