找到至少有一条记录满足条件的情况。

huangapple go评论52阅读模式
英文:

Find records where at least one fulfills a condition

问题

我想查找Mongo中的一些记录,它们都满足某个条件,并且至少有一个满足第二个独立条件。

示例:

假设记录具有 counterisHandled 参数(分别为 NumberBoolean)。我想查找所有 counter >= 100 的记录,并且至少有一个满足第一个条件的记录也具有 isHandled 设置为 false

假设我有以下记录:

[
  {
    "_id": "1",
    "counter": 50,
    "isHandled": false
  },
  {
    "_id": "2",
    "counter": 50,
    "isHandled": true
  },
  {
    "_id": "3",
    "counter": 100,
    "isHandled": true
  },
  {
    "_id": "4",
    "counter": 100,
    "isHandled": true
  },
  {
    "_id": "5",
    "counter": 120,
    "isHandled": false
  },
  {
    "_id": "6",
    "counter": 100,
    "isHandled": true
  }
]

还有 threshold = 100。我的查询应该返回 _id"3", "4", "5""6" 的记录。但是,如果记录 "5" 不存在,那么不应返回任何记录。原因是因为所有满足第一个条件(counter)的记录都不满足第二个条件。

我的第一部分可能是 { counter: { $gte: threshold } }

有没有办法实现这个?使用一些管道?

英文:

I'm looking to find some records from Mongo where they all fulfill some condition and that at least one of them fulfills a second, separate, condition.

Example:

Say records have counter & isHandled parameters (Number & Boolean respectfully).
I'd like to find all records where counter >= 100 and that at least one of the records that fulfill the first requirement also has isHandled set to false.

Say I have these records:

[
  {
    "_id": "1",
    "counter": 50,
    "isHandled": false
  },
  {
    "_id": "2",
    "counter": 50,
    "isHandled": true
  },
  {
    "_id": "3",
    "counter": 100,
    "isHandled": true
  },
  {
    "_id": "4",
    "counter": 100,
    "isHandled": true
  },
  {
    "_id": "5",
    "counter": 120,
    "isHandled": false
  },
  {
    "_id": "6",
    "counter": 100,
    "isHandled": true
  }
]

And also threshold = 100. My query should return the records with _id "3", "4", "5" & "6". However, if record "5" was not there, then no record should be returned. The reason is that since all of the records that satisfy the first condition (counter), none satisfy the second condition.

My first part might be { counter: { $gte: threshold } }.

Any idea how I can achieve this? Some sort of pipeline?

答案1

得分: 1

以下是已翻译的内容:

  1. $match 条件:{$gte: threshold},用于筛选计数大于等于阈值的文档。
  2. 使用 $setWindowFields 计算 isHandled 字段的 $rank。这里的技巧是,如果所有记录都为真,它们将共享排名:1。如果有一些文档为假,那么假文档将具有排名:1,而真文档将具有排名:2。
  3. 使用 $match 条件,通过 $or 条件筛选所有记录,其中条件是 isHandled 为假或 rank 为 2(这意味着它们是真实文档,但存在一些假文档使其排名为2)。
英文:

You can do the followings in an aggregation pipeline:

  1. $match with counter : {$gte: threshold}
  2. $setWindowFields to compute $rank for isHandled field. The trick here is if all records are true, they will all share the rank: 1. If some documents are false, the false documents will have rank: 1 and true documents will have rank: 2
  3. $match all records by a $or condition on isHandled: false or rank: 2( that means they are true documents, but there exists some false documents to make it having rank 2)
db.collection.aggregate([
  {
    "$match": {
      counter: {
        $gte: 100
      }
    }
  },
  {
    "$setWindowFields": {
      "partitionBy": null,
      "sortBy": {
        "isHandled": 1
      },
      "output": {
        "rank": {
          $denseRank: {}
        }
      }
    }
  },
  {
    $match: {
      $expr: {
        $or: [
          {
            $eq: [
              "$isHandled",
              false
            ]
          },
          {
            $eq: [
              "$rank",
              2
            ]
          }
        ]
      }
    }
  },
  {
    $unset: "rank"
  }
])

Mongo Playground

EDIT: thanks for @Noel 's comment. Changed to use $denseRank from $rank

答案2

得分: 0

const threshold = 100;

db.collection.find({ 
  $and: [
    { counter: { $gte: threshold } }, 
    { 
      $or: [
        { isHandled: false }, 
        { isHandled: { $exists: false } }
      ]
    }
  ]
});
英文:

You can try this one:

const threshold = 100;

db.collection.find({ 
  $and: [
    { counter: { $gte: threshold } }, 
    { 
      $or: [
        { isHandled: false }, 
        { isHandled: { $exists: false } }
      ]
    }
  ]
});

huangapple
  • 本文由 发表于 2023年2月14日 20:04:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75447593.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定