我对如何使用Aggregate来获得非常具体类型的结果有点迷茫. 我的数据库文档具有以下格式

{
  _id: 122434
  houseDetails: {
     hasBedroom: {
       flag: true,
     },
     hasKitchen: {
       flag: false
     },
     hasBalcony: {
       flag: false
     },
     hasFoyer: {
       flag: true
     },
  }
}

(这是文件 struct 的基本例子,细节有所不同)

我正在try 查询嵌套的houseDetails个属性为真的所有文档. 所以最后我希望结果看起来像是

{
  _id: 122434,
  houseDetails: [hasBedroom, hasFoyer]
}

我可以使用$Match查找其中至少有一个属性为True的所有文档,但我似乎不知道如何将值为True的名称投影到数组中.

推荐答案

一种 Select 是:

  1. 使用$objectToArray根据键和值创建数组
  2. $filterit只保留true个值
  3. 如果设置为$match,则只保留具有"有效"数据的文档.
  4. 使用$map设置项目的格式
db.collection.aggregate([
  {$project: {houseDetails: {$objectToArray: "$houseDetails"}}},
  {$project: {
      houseDetails: {
        $filter: {
          input: "$houseDetails",
          cond: {$eq: ["$$this.v.flag", true]}
        }
      }
    }
  },
  {$match: {"houseDetails.0": {"$exists": true}}},
  {$project: {
      houseDetails: {
        $map: {
          input: "$houseDetails",
          in: "$$this.k"
        }
      }
    }
  }
])

看看它在playground example号公路上是如何工作的

您也可以使用$reduce仅通过三个步骤完成此操作:

db.collection.aggregate([
  {$project: {houseDetails: {$objectToArray: "$houseDetails"}}},
  {$project: {
      houseDetails: {
        $reduce: {
          input: "$houseDetails",
          initialValue: [],
          in: {
            $setUnion: [
              "$$value",
              {$cond: [{$eq: ["$$this.v.flag", true]}, ["$$this.k"], []]}
            ]
          }
        }
      }
    }
  },
  {$match: {"houseDetails.0": {"$exists": true}}},

看看它在playground example - reduce号公路上是如何工作的

Node.js相关问答推荐

Node.js promise 循环中的所有多个API调用

无法使用NPM安装REDUX和DATEPPICER

在对象的嵌套数组中使用$lookup,创建多个记录作为响应,mongodb

Mongoose:如何使用填充进行查找

Nest Js - 在 multer 拦截器中如何设置最大文件上传大小并进行可选文件上传

在 .htaccess 中从非 www 切换到 www 后如何解决无法访问该站点?

node_modules/preact/src/jsx.d.ts:2145:22 - 错误 TS2304:找不到名称SVGSetElement

加速 sequelize ORM 中的查询

NestJS 共享模块的问题

来自 Node-aws 的 Dynamo Local:所有操作都失败无法对不存在的表执行操作

Node.js + Express + Handlebars.js + 局部视图

Puppeteer 错误:未下载 Chromium 修订版

如何让should.be.false语法通过 jslint?

Node.js:socket.io 关闭客户端连接

我可以有条件地将 where() 子句添加到我的 knex 查询吗?

Mongoose - 保存字符串数组

在 Node.js 中获取终端的宽度

expressjs app.VERB 调用中的 next() 和 next('route') 有什么区别?

mongoose 填充与对象嵌套

Mongoose - 验证邮箱语法