Query Mon go массив документов на основе другого массива в том же документе - PullRequest
2 голосов
/ 27 февраля 2020

У меня пн go документы в следующем формате:

{
    "_id":{
        "$oid":"1237563648fe93j3b5"
    },
    "stage_id":{
        "$oid":"1213241423nn552l54j"
    },
    "payload":[
        {
            "_data":{
                "name":"name1",
                "description":"",
                "parent":"",
                "status":"NOT READY"
            }
        },
        {
            "_data":{
                "name":"name2",
                "description":"MS Visio",
                "parent":"A7704",
                "status":"OPERATING"
            }
        },

        {
            "_data":{
                "assetnum":"name3",
                "description":"MS Visio",
                "parent":"7127",
                "status":"OPERATING"
            }
        }
    ],
    "response":[
        {
            "_data":{
                "Error":{
                    "message":"AVJPA - The record already exists. 
                    "attrname":"name",
                    "reasonCode":"AVJPA",
                    "status":"400"
                }
            },
            "_meta":{
                "status":"400"
            }
        },
        {
            "_data":{
                "Error":{
                    "message":"AVJPA - The record already exists. 
                    "attrname":"name",
                    "reasonCode":"AVJPA",
                    "status":"400"
                }
            },
            "_meta":{
                "status":"400"
            }
        },
        {
            "_data":{
                "message":"success"
            },
            "_meta":{
                "status":"204"
            }
        }
    ]
}

В этом формате есть несколько документов. Массив response - это ответы для элементов в массиве payload, которые были отправлены в конечную точку API. Таким образом, index 0 в массиве ответов является ответом для полезной нагрузки index 0 в массиве полезных данных. Теперь я хотел бы отфильтровать коллекцию и получить полезные данные, где ответ reasonCode IS AVJPA. Как это можно сделать? Я использую следующий код, чтобы выяснить, существуют ли ответы с Error, но не уверен, как найти полезные данные, соответствующие ответу.

logs.find({
    "stage_id":1213241423nn552l54j
    $elemMatch: {"_responsedata.Error": {$exists: true}}
})

где logs - это название моей коллекции. Я запускаю этот код в Python и использую клиентскую библиотеку PyMon go.

1 Ответ

0 голосов
/ 27 февраля 2020

Проверьте, соответствует ли это вашим требованиям:

db.logs.aggregate([
  {
    $match: {
      "stage_id": ObjectId("5a934e000102030405000001"),
      "response": {
        $elemMatch: {
          "_data.Error": {
            $exists: true
          }
        }
      }
    }
  },
  {
    $addFields: {
      tmp: "$payload"
    }
  },
  {
    $unwind: {
      path: "$tmp",
      includeArrayIndex: "idx",
      preserveNullAndEmptyArrays: false
    }
  },
  {
    $match: {
      $expr: {
        $eq: [
          {
            $let: {
              vars: {
                input: {
                  $arrayElemAt: [
                    "$response",
                    "$idx"
                  ]
                }
              },
              in: "$$input._data.Error.reasonCode"
            }
          },
          "AVJPA"
        ]
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      stage_id: {
        $first: "$stage_id"
      },
      payload: {
        $push: {
          $arrayElemAt: [
            "$payload",
            "$idx"
          ]
        }
      },
      response: {
        $push: {
          $arrayElemAt: [
            "$response",
            "$idx"
          ]
        }
      },

    }
  }
])

MongoPlayground

...