如何在MongoDB中的$ match阶段使用$ ifNull

时间:2018-06-16 06:44:51

标签: match ifnull

我在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,但它在执行时显示错误。

我的查询有什么问题?

1 个答案:

答案 0 :(得分:0)

查询的第一个问题是$ 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计算值并在以后的步骤中使用

{
  $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")
    } 
  } 
}