web-dev-qa-db-ja.com

$ lookupの結果の$ match

次のmongoコードがあります:

db.users.aggregate([
    { 
        $match: { 
            $and: [
                { UserName: { $eq: 'administrator' } }, 
                { 'Company.CompanyName': { $eq: 'test' } }
            ]                   
        } 
    },
    { 
        $lookup: { 
            from: "companies", 
            localField: "CompanyID", 
            foreignField: "CompanyID", 
            as: "Company" 
        } 
    },
])

$lookupすばらしいコードの一部。私は次の結果を得ました:

enter image description hereenter image description here

しかし、$matchコードに、何ももたらしません。

問題は2番目の一致にあることがわかりました:{ 'Company.CompanyName': { $eq: 'test' } }、しかし、私はそれが何が悪いのか理解できません。何か案は?

UPDATE:

私も試しました$unwind上の$lookup結果、しかし運はありません:

db.users.aggregate([
    { 
        $match: { 
            $and: [
                { UserName: { $eq: 'administrator' } }, 
                { 'Company.CompanyName': { $eq: 'edt5' } }
            ] 
        } 
    },
    {   unwind: '$Company' },
    { 
        $lookup: { 
            from: 'companies', 
            localField: 'CompanyID', 
            foreignField: 'CompanyID', 
            as: 'Company' 
        } 
    },
])
12
AlexBerd

MongoDB 3.4では、$addFieldsパイプラインと$filter演算子は、指定された条件に一致する要素を持つCompany配列のみを返します。その後、$filter$arrayElemAt本質的に$unwind配列を平坦化する機能。

上記の概念を理解するには、この例に従ってください。

db.users.aggregate([
    { "$match": { "UserName": "administrator" } },
    { 
        "$lookup": { 
            "from": 'companies', 
            "localField": 'CompanyID', 
            "foreignField": 'CompanyID', 
            "as": 'Company' 
        } 
    },
    {
        "$addFields": {
            "Company": {
                "$arrayElemAt": [
                    {
                        "$filter": {
                            "input": "$Company",
                            "as": "comp",
                            "cond": {
                                "$eq": [ "$$comp.CompanyName", "edt5" ]
                            }
                        }
                    }, 0
                ]
            }
        }
    }
])
20
chridam

以下は、mongoDB 3.6以降の場合です。

とすれば:

  • フィールドusersを持つコレクションCompanyIDと、フィールドcompaniesを持つCompanyIDのコレクションがあります
  • Companiesを照合して、UsersCompanyIDを検索します。

    • 各ユーザーは条件に一致する必要があります:User.UserNameadministratorと等しい
    • Companyの各Userは条件に一致する必要があります:CompanyName等しいedt5

次のクエリが機能します。

  db.users.aggregate([
    { $match: { UserName: 'administrator' } },
    {
      $lookup: {
        from: 'companies',
        as: 'Company',
        let: { CompanyID: '$CompanyID' },
        pipeline: [
          {
            $match: {
              $expr: {
                $and: [
                  { $eq: ['$CompanyID', '$$CompanyID'] },
                  { $eq: ['$CompanyName', 'edt5'] },
                ]
              }
            }
          }
        ]
      }
    },
  ])

説明:これは、単純な外部/ローカルフィールドの等価一致よりも複雑な条件で左結合クエリを実行する方法です。

localFieldforeignFieldを使用する代わりに、次を使用します。

  • letオプション。ローカルフィールドを変数にマッピングできます。
  • pipelineオプション。集約Arrayを指定できます。

pipelineでは、$matchフィルタ、$exprletで以前に定義された変数を再利用できます。

$ lookupの詳細

素敵なチュートリアル