【问题标题】:How to use $ifNull in $match stage in MongoDB如何在 MongoDB 的 $match 阶段使用 $ifNull
【发布时间】:2018-11-25 21:24:45
【问题描述】:

我在 mongodb 的聚合中添加了如下条件。

"$match" : {                
$ifNull: ["$startDate", "$createdAt"] : {"$gte": ISODate("2018-06-01 10:03:46.000Z"), "$lte": ISODate("2018-06-29 10:03:46.000Z")}              
}

当我检查startDate 是否未定义或为空时,我得到createdAt 但它在执行时显示错误。

我的查询有什么问题?

【问题讨论】:

  • 您的查询令人困惑。你到底想做什么?你期望的结果是什么?

标签: match ifnull


【解决方案1】:

您的查询的第一个问题是您的 $match 对象不是有效的 js 对象。您不能用这样的东西替换对象键。此外,$match 还有其他限制。

mongodb match documentation中所述

$match 查询语法与读操作查询语法相同;即 $match 不接受原始聚合表达式。要在 $match 中包含聚合表达式,请使用 $expr 查询表达式:

{ $match: { $expr: { <aggregation expression> } } }

$ifNull 可以像这样在 $match 中使用;

{ 
  $match: { 
    $expr: { 
      $gte: [
          {$ifNull: ["$startDate", "$createdAt"]},
          ISODate("2018-06-01 10:03:46.000Z")
        ] 
    } 
  } 
}

您的查询的可能版本:##

只使用 $match:

{ 
  $match: { 
    $expr: { 
      $and: [
        { $gte: [
          {$ifNull: ["$startDate", "$createdAt"]},
          ISODate("2018-06-01 10:03:46.000Z")
        ]}, 
        { $lte: [
          {$ifNull: ["$startDate", "$createdAt"]},
          ISODate("2018-06-29 10:03:46.000Z")
        ]}
      ]
    } 
  } 
}

或者,您可以使用$project 计算值并使用在后面的步骤中

注意:这会影响性能,因为 Mongo 在匹配数据时将无法使用索引。

{
  $project: {
    'computedStartDate' : {$ifNull: ["$startDate", "$createdAt"]}
  }
},
{ 
  $match: { 
    "computedStartDate": 
      {"$gte": ISODate("2018-06-01 10:03:46.000Z"), "$lte": ISODate("2018-06-29 10:03:46.000Z")
    } 
  } 
}

【讨论】:

  • 很棒的答案!值得注意的是,带有$project 的第二个变体会表现得更差,因为它不会使用索引(如果$startDate$createdAt 上有索引)
猜你喜欢
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-25
  • 2018-12-19
  • 1970-01-01
  • 2019-05-30
相关资源
最近更新 更多