【问题标题】:MongoDB Remove or Limit fields conditional aggregationMongoDB 删除或限制字段条件聚合
【发布时间】:2019-09-21 19:01:57
【问题描述】:

我在编写查找/聚合 mongo 查询时遇到问题,我的要求是获取所有文档,但条件如下:

假设我有 2 个文档:

{
  _id: 5ccaa76939d95d395791efd2,
  name: 'John Doe',
  email: 'john.doe@foobar.com',
  private: true
}

{
  _id: 5ccaa76939d95d395791efd2,
  name: 'Jane Doe',
  email: 'jane.doe@foobar.com',
  private: false
} 

现在我想了解的查询是如果字段private 为真,那么当我查询时,如果private 为真,我必须获取除电子邮件字段之外的所有文档,如下所示:

{
 _id: 5ccaa76939d95d395791efd2,
 name: 'John Doe',
 private: true
}

{
 _id: 5ccaa76939d95d395791efd2,
 name: 'Jane Doe',
 email: 'jane.doe@foobar.com',
 private: false
} 

在聚合()中尝试了$redact$cond$$PRUNE$$DESCEND 以及遇到了$$REMOVE(看起来是最新功能),但无法获得所需的输出。请帮我解决查询

【问题讨论】:

    标签: mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    您可以使用$$REMOVE 从返回的文档中删除字段。

    db.collection.aggregate([ 
      { "$addFields": {
        "email": {
          "$cond": [
            { "$eq": ["$private", true] },
            "$$REMOVE",
            "$email"
          ]
        }
      }}
    ])
    

    MongoPlayground

    【讨论】:

    • 非常感谢您的查询,这确实有效。!!
    【解决方案2】:

    感谢 Anthony Winzlet,他的解决方案非常有效。

    如果有人遇到同样的问题并且需要包含多个字段,我正在编写此方法:

    function condition(privateFieldLimitationArray, publicFieldLimitationArray) {
      const condition = {};
    
      privateFieldLimitationArray.map((d, i) => {
        condition[d] = {
          "$cond": [
          { "$eq": ["$private", true] },
          "$$REMOVE",
          publicFieldLimitationArray.includes(d) ? '$$REMOVE' : '$'+d
          ]
        }
      });
    
      return condition;
    }
    

    然后,你可以使用上面的函数:

    const privateLimitationArray = ['updatedAt', 'createdAt', 'email', 'lname', 'friendslist', '__v'];
    
    const publicLimitationArray = ['updatedAt', 'createdAt', '__v'];
    
    
    YourModel.aggregate([
            {
              $match: {
                // Your query to find by
              }
            }, {
              "$addFields": condition(privateLimitationArray, publicLimitationArray)
            }
        ])
        .then(result => {
          // handle result
        })
        .catch(error => {
          // handle error
        });
    
    
    

    【讨论】:

      猜你喜欢
      • 2018-08-06
      • 2015-03-25
      • 2022-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多