如何编写以下MongoDB查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何编写以下MongoDB查询相关的知识,希望对你有一定的参考价值。

假设我有以下foobar集合:

{
  "foobar": [
    {
      "_id": "abc",
      "history": [
        {
          "type": "foo",
          "timestamp": 123456789.0
        },
        {
          "type": "bar",
          "timestamp": 123456789.0
        }
      ]
    },
    {
      "_id": "dfg",
      "history": [
        {
          "type": "baz",
          "timestamp": 123456789.0
        },
        {
          "type": "bar",
          "timestamp": 123456789.0
        }
      ]
    },
    {
      "_id": "hij",
      "history": [
        {
          "type": "foo",
          "timestamp": 123456789.0
        },
        {
          "type": "bar",
          "timestamp": 123456789.0
        },
        {
          "type": "foo",
          "timestamp": 123456789.0
        }
      ]
    }
  ]
}

如何查询($gte / $ltefoobar项目基于他们的timestamp项目中的history道具,但使用timestamp项目中的type: "foo"

如果没有type等于foo的子文档,则整个文档被过滤掉,如果有多个子文档type等于foo那么它可以匹配任何人。

答案

您可以尝试以下聚合:

var threshold = 123456788;
db.foobar.aggregate([
    {
        $addFields: {
            foobar: {
                $filter: {
                    input: "$foobar",
                    as: "doc",
                    cond: {
                        $let: {
                            vars: { 
                                foo: {
                                    $arrayElemAt: [
                                        {
                                            $filter: {
                                                input: "$$doc.history",
                                                as: "history",
                                                cond: {
                                                    $eq: [ "$$history.type", "foo" ]
                                                }
                                            }
                                        },
                                        0]
                                }
                            },
                            in: {
                                $gt: [ "$$foo.timestamp", threshold ]
                            }
                        }
                    }
                }
            }
        }
    }
])

$addFields可用于覆盖现有字段(foobar)。要筛选出与您的条件不匹配的所有子文档,您可以使用$filter(外部文档)。对于每个foobar文档,您可以使用$let来定义临时变量foo。你需要内部$filter来获得所有history元素,其中typefoo然后$arrayElemAt获得第一个。然后你只需要$gt$lt来应用你的比较。

对于那些没有foo的子文档,将返回undefined,然后在$gt阶段过滤掉。

以上是关于如何编写以下MongoDB查询的主要内容,如果未能解决你的问题,请参考以下文章

如何将代码片段存储在 mongodb 中?

如何在 Symfony 中为使用 queryBuilder 构建的 MongoDB 查询编写单元测试

如何编写代码以通过关键字在 MongoDB 中查找项目?

如何使用 mongoDB 条件查询在 java 中获得更干净的代码 [重复]

如何在 mongoid dsl 中编写 mongodb $near 查询?

如何创建一个查询来查找 2 个数字之间的值,这些数字是 MongoDB 中的字符串类型