在集合中存在一个字段的条件匹配

发布于 2025-02-08 09:42:43 字数 809 浏览 2 评论 0原文

请帮我。我有一个集合如下,

[
   {
      "_id":{
         "$oid":"62a3673660e2f16c7a7bc088"
      },
      "merchant":{
         "$oid":"62a3640560e2f16c7a7bc078"
      },
      "title":"24 Test 1",
      "filter_conditions":{
         "city":[
            "AAA",
            "BBB",
            "CCC",
            "DDD"
         ],
         "state":[
            
         ],
         "pincode":[
            "12345"
         ]
      }
   },
   {
      "_id":{
         "$oid":"62a3673660e2f16c7a7bc089"
      },
      "merchant":{
         "$oid":"62a3640560e2f16c7a7bc079"
      },
      "title":"24 Test 2",
      "filter_conditions":{
         "city":[
            "AAA",
            "BBB"
         ]
      }
   }
]

我想根据Pincode/City/State过滤数据

。 Elseif City在这里匹配并忽略状态 否则匹配状态

Please help me. I have a collection as below

[
   {
      "_id":{
         "$oid":"62a3673660e2f16c7a7bc088"
      },
      "merchant":{
         "$oid":"62a3640560e2f16c7a7bc078"
      },
      "title":"24 Test 1",
      "filter_conditions":{
         "city":[
            "AAA",
            "BBB",
            "CCC",
            "DDD"
         ],
         "state":[
            
         ],
         "pincode":[
            "12345"
         ]
      }
   },
   {
      "_id":{
         "$oid":"62a3673660e2f16c7a7bc089"
      },
      "merchant":{
         "$oid":"62a3640560e2f16c7a7bc079"
      },
      "title":"24 Test 2",
      "filter_conditions":{
         "city":[
            "AAA",
            "BBB"
         ]
      }
   }
]

I want to filter data based on pincode/city/state

if pincode is present match it and ignore city and state
elseif city is present match it and ignore state
else match on state

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薔薇婲 2025-02-15 09:42:43

您可以使用$ filter的聚合管道使用:

  1. 如果文档上不存在任何字段,请使用空数组创建它。
  2. 使用$ filter对文档进行评分,因此匹配的pincode的等级为100,用于匹配city> city是10的是10 /code>是1。使用$ max仅保留最佳成绩。
  3. 以最高成绩返回文档。
db.collection.aggregate([
  {$set: {
      "filter_conditions.pincode": {$ifNull: ["$filter_conditions.pincode", []]},
      "filter_conditions.city": {$ifNull: ["$filter_conditions.city", []]},
      "filter_conditions.state": {$ifNull: ["$filter_conditions.state", []]}
    }
  },
  {$set: {
      grade: {
        $max: [
          {$multiply: [
              {$size: {
                  $filter: {
                    input: "$filter_conditions.pincode",
                    as: "item",
                    cond: {$eq: ["$item", "12345"]}
                  }
                }
              }, 100]
          },
          {$multiply: [
              {$size: {
                  $filter: {
                    input: "$filter_conditions.city",
                    as: "item",
                    cond: {$eq: ["$item", "BBB"]}
                  }
                }
              }, 10]
          },
          {$multiply: [
              {$size: {
                  $filter: {
                    input: "$filter_conditions.state",
                    as: "item",
                    cond: {$eq: ["$item", "AL"]}
                  }
                }
              }, 1]
          }
        ]
      }
    }
  },
  {$sort: {grade: -1}},
  {$limit: 1}
])

查看在 Playground示例示例

You can use an aggregation pipeline with a $filter:

  1. If any of the fields does not exist on the doc, create it with an empty array.
  2. Use $filter to grade the docs, so the grade for matching pincode is 100, for matching city is 10 for matching state is 1. Use $max to keep the best grade only.
  3. Return the doc with highest grade.
db.collection.aggregate([
  {$set: {
      "filter_conditions.pincode": {$ifNull: ["$filter_conditions.pincode", []]},
      "filter_conditions.city": {$ifNull: ["$filter_conditions.city", []]},
      "filter_conditions.state": {$ifNull: ["$filter_conditions.state", []]}
    }
  },
  {$set: {
      grade: {
        $max: [
          {$multiply: [
              {$size: {
                  $filter: {
                    input: "$filter_conditions.pincode",
                    as: "item",
                    cond: {$eq: ["$item", "12345"]}
                  }
                }
              }, 100]
          },
          {$multiply: [
              {$size: {
                  $filter: {
                    input: "$filter_conditions.city",
                    as: "item",
                    cond: {$eq: ["$item", "BBB"]}
                  }
                }
              }, 10]
          },
          {$multiply: [
              {$size: {
                  $filter: {
                    input: "$filter_conditions.state",
                    as: "item",
                    cond: {$eq: ["$item", "AL"]}
                  }
                }
              }, 1]
          }
        ]
      }
    }
  },
  {$sort: {grade: -1}},
  {$limit: 1}
])

See how it works on the playground example

鹤仙姿 2025-02-15 09:42:43

您可以使用嵌套$ cond来执行过滤。

概念:

  1. 检查filter_conditions.pincode

    1.1。如果为true,请在filter_conditions.pincode array中检查该值。

    1.2。否则,继续进行 2

  2. 检查filter_conditions.city

    2.1。如果为true,请在filter_conditions.city array中检查该值。

    2.2。否则,继续进行 3

  3. 检查filter_conditions.state array中是否存在值(默认为空数组,如果不存在数组)。

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $cond: {
          if: {
            $ne: [
              "$filter_conditions.pincode",
              undefined
            ]
          },
          then: {
            $in: [
              "", // pincode value
              "$filter_conditions.pincode"
            ]
          },
          else: {
            $cond: {
              if: {
                $ne: [
                  "$filter_conditions.city",
                  undefined
                ]
              },
              then: {
                $in: [
                  "", // city value
                  "$filter_conditions.city"
                ]
              },
              else: {
                $in: [
                  "", // state value
                  {
                    $ifNull: [
                      "$filter_conditions.state",
                      []
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    }
  }
])

示例mongo playground

You can work with nested $cond to perform the filtering.

Concept:

  1. Check filter_conditions.pincode is existed.

    1.1. If true, check the value is existed in filter_conditions.pincode array.

    1.2. Else, proceed to 2.

  2. Check filter_conditions.city is existed.

    2.1. If true, check the value is existed in filter_conditions.city array.

    2.2. Else, proceed to 3.

  3. Check if value is existed in filter_conditions.state array (default as empty array if the array is not existed).

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $cond: {
          if: {
            $ne: [
              "$filter_conditions.pincode",
              undefined
            ]
          },
          then: {
            $in: [
              "", // pincode value
              "$filter_conditions.pincode"
            ]
          },
          else: {
            $cond: {
              if: {
                $ne: [
                  "$filter_conditions.city",
                  undefined
                ]
              },
              then: {
                $in: [
                  "", // city value
                  "$filter_conditions.city"
                ]
              },
              else: {
                $in: [
                  "", // state value
                  {
                    $ifNull: [
                      "$filter_conditions.state",
                      []
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    }
  }
])

Sample Mongo Playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文