несколько условий в $ match в mongodb - PullRequest
2 голосов
/ 20 апреля 2020

У меня есть коллекция AccountSupport. У меня есть массив свойств поддержки. Я хочу отфильтровать запись по родительскому свойству и свойству массива

db = {
  "AccountSupport": [
    {
    "_id" : ObjectId("5e9c6170b38c373530c5b00a"),
    "accountName" : "domestic",
    "supports" : [ 
        {
            "subject" : "Traverse",
            "desc" : "Travers support consolidation",
        }, 
        {
            "subject" : "Non Traverse",
            "desc" : "Non Travers support consolidation",
        },
        {
            "subject" : "Domestic Traverse",
            "desc" : "Domestic Travers support consolidation",
        }       
    ],

  }

Я хочу отфильтровать по accountName и support.subject.

Ниже мой запрос

db.AccountSupport.aggregate([
  {
    "$match": {
      "$and": [
        {
          "supports.subject": "Traverse"
        },
        {
          "accountName": "domestic"
        }
      ]
    }
  },
  {
    "$unwind": "$supports"
  },
  {
    "$project": {
      "SupportName": "$supports.subject",
      "desc": "$supports.desc"
    }
  }
])

Приведенный выше запрос возвращает мне все опоры определенного accountName, тогда как мне нужен только один объект соответствующего субъекта. Это самый простой способ сделать это?

MongoPlayGround

MongoPlayGround для моего запроса

Ответы [ 3 ]

2 голосов
/ 20 апреля 2020

Потребовалось немного поэкспериментировать, но попробуйте это:

db.AccountSupport.aggregate([
  {
    $match: {
      "accountName": "domestic",
      "supports.subject": "Traverse"
    }
  },
  {
    $project: {
      accountName: "$accountName",
      subject: {
        $filter: {
          input: "$supports",
          as: "supports",
          cond: {
            $eq: [
              "$$supports.subject",
              "Traverse"
            ]
          }
        }
      },
      _id: 0
    }
  }
])

Что возвращает:

[
  {
    "accountName": "domestic",
    "subject": [
      {
        "desc": "Travers support consolidation",
        "subject": "Traverse"
      }
    ]
  }
]
0 голосов
/ 21 апреля 2020

Ниже приведен запрос для получения необходимого результата, но я не уверен, что это лучший метод, поскольку остальные опубликованные ответы также хорошо работают для указанного требования

db.AccountSupport.find({'accountName': 'domestic' },
                      { 
                         'supports': 
                                { 
                                  '$elemMatch': { 'subject': 'Traverse'}
                                }
                       })
0 голосов
/ 20 апреля 2020

Один из вариантов - просто добавить еще один шаг $match в запрос агрегации. Поскольку $unwind разбивает ваш do c на 3 документа, вы можете сопоставить индивидуальный do c, который вы хотите вернуть. Решение $filter от james выглядит заслуживающим изучения и может быть более простым для вас.

Запрос:

db.AccountSupport.aggregate([
  {
    "$match": {
      "$and": [
        {
          "supports.subject": "Traverse"
        },
        {
          "accountName": "domestic"
        }
      ]
    }
  },
  {
    "$unwind": "$supports"
  },
  {
    "$match": {
      "supports.subject": "Traverse"
    }
  },
  {
    "$project": {
      "SupportName": "$supports.subject",
      "desc": "$supports.desc"
    }
  }
])

Результат:

[
  {
    "SupportName": "Traverse",
    "_id": ObjectId("5e9c6170b38c373530c5b00a"),
    "desc": "Travers support consolidation"
  }
]

MongoPlayground

...