【问题标题】:MongoDB query using values priority使用值优先级的 MongoDB 查询
【发布时间】:2020-04-24 18:31:29
【问题描述】:

我的收藏中有以下文档:

/* 1 */
{
    "_id" : ObjectId("5ea32d11f213c27c35395fd3"),
    "name" : "Test",
    "state" : "OH",
    "code" : "CDM"
}

/* 2 */
{
    "_id" : ObjectId("5ea32d29f213c27c35395fe0"),
    "name" : "Test1",
    "state" : "ALL",
    "code" : "CDM"
}

/* 3 */
{
    "_id" : ObjectId("5ea32d38f213c27c35395fe7"),
    "name" : "Test2",
    "state" : "OH",
    "code" : "ALL"
}

/* 4 */
{
    "_id" : ObjectId("5ea32d46f213c27c35395feb"),
    "name" : "Test3",
    "state" : "ALL",
    "code" : "ALL"
}

尝试根据statecode 过滤文档。

但是如果没有找到特定的statecode 则几乎没有条件,则使用值ALL 进行搜索

示例 1:

状态 = CA

代码 = CDM

然后只返回

  {
    "_id" : ObjectId("5ea32d29f213c27c35395fe0"),
    "name" : "Test1",
    "state" : "ALL",
    "code" : "CDM"
}

示例 2:

状态 = CA

代码 = DCM

然后只返回

  {
    "_id" : ObjectId("5ea32d46f213c27c35395feb"),
    "name" : "Test3",
    "state" : "ALL",
    "code" : "ALL"
}

等等。

我尝试的查询是 state = CA ,code = CDM:

db.getCollection('user_details').aggregate([

{'$match': { 'state': {'$in': ['CA','ALL']},
'code': {'$in': ['CDM','ALL']}}}

])

返回的是:

/* 1 */
{
    "_id" : ObjectId("5ea32d29f213c27c35395fe0"),
    "name" : "Test1",
    "state" : "ALL",
    "code" : "CDM"
}

/* 2 */
{
    "_id" : ObjectId("5ea32d46f213c27c35395feb"),
    "name" : "Test3",
    "state" : "ALL",
    "code" : "ALL"
}

预期是:

{
        "_id" : ObjectId("5ea32d29f213c27c35395fe0"),
        "name" : "Test1",
        "state" : "ALL",
        "code" : "CDM"
    }

你能帮忙解决这个问题吗?

【问题讨论】:

  • 如果两者都找不到,您是否必须返回{ "_id" : ObjectId("5ea32d46f213c27c35395feb"), "name" : "Test3", "state" : "ALL", "code" : "ALL" }
  • @whoami 是的......
  • 另外,如果您同时拥有{ "_id" : ObjectId("5ea32d29f213c27c35395fe0"), "name" : "Test1", "state" : "ALL", "code" : "CDM" }{ "_id" : ObjectId("5ea32d29f213c27c35395fe1"), "name" : "Test2", "state" : "CA", "code" : "CDM" },那么必须返回什么 - 只有第二个文档?
  • 第二个(当 state = CA , code = CDM 时)
  • 不应退回任何文件 ?好的,这很奇怪(请针对这些情况编辑问题) - 考虑到所有这些复杂情况,您可以更好地选择在代码卸载 DB 上的压力时这样做,同时您可以试试这个 :: (mongoplayground.net/p/ejx5TCZyNEr)

标签: mongodb mongodb-query


【解决方案1】:

试试下面的查询:

db.collection.find({
  $or: [
    {
      state: "CA",
      code: "CDM"
    },
    {
      state: "ALL",
      code: "CDM"
    },
    {
      state: "ALL",
      code: "ALL"
    },
    {
      state: "CA",
      code: "ALL"
    }
  ]
})

所以基本上你不能在一个查询中实现你正在寻找的东西,你可以尝试聚合运算符 $facet$switch 来做到这一点,但我不喜欢这样做,因为 facet 中的每个阶段都会做对整个集合的数据进行给定的操作。取而代之的是使用上述查询获得更少的文档,并且在您的代码中您实际上可以过滤最适合的文档,这将是简单且高效的。不要忘记在 DB 上维护indexes

测试: mongoplayground

【讨论】:

    【解决方案2】:

    试试这个:

    db.user_details.aggregate([
      {
        $facet: {
          match: [
            {
              "$match": {
                $or: [
                  {
                    "state": "CA",
                    "code": {
                      "$in": [ "CDM", "ALL" ]
                    }
                  },
                  {
                    "state": {
                      "$in": [ "CA", "ALL"]
                    },
                    "code": "CDM"
                  }
                ]
              }
            }
          ],
          all: [
            {
              "$match": {
                "state": "ALL",
                code: "ALL"
              }
            }
          ]
        }
      },
      {
        $project: {
          match: {
            $cond: [
              {
                $eq: [ { $size: "$match" },  0]
              },
              "$all",
              "$match"
            ]
          }
        }
      },
      {
        $unwind: "$match"
      },
      {
        $replaceWith: "$match"
      }
    ])
    

    MongoPlayground

    【讨论】:

      猜你喜欢
      • 2012-01-17
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 2021-01-09
      • 1970-01-01
      • 2012-11-27
      相关资源
      最近更新 更多