如何仅在特定条件下执行 MongoDB 聚合阶段之一?

Posted

技术标签:

【中文标题】如何仅在特定条件下执行 MongoDB 聚合阶段之一?【英文标题】:How to perform one of the MongoDB aggregation stage only under certain condition? 【发布时间】:2020-08-18 08:19:38 【问题描述】:

如果某些条件评估为真或假,有什么方法可以省略 MongoDB 聚合阶段之一?

我正在构建餐厅搜索器应用程序,您可以在其中按名称、他们提供的美食等查找餐厅。用户可以输入的字段之一是餐厅 name 字段。如果用户将其留空,我不想在名称字段上执行 $text 搜索,但我不知道如何实现。

这是我的示例代码,但是它不起作用,因为它会触发警报 MongoError: unknown top level operator: $cond

const  borough, cuisine, name  = req.body;

  try 
    const restaurantCollection = databaseFunctions
      .getDatabase()
      .collection('restaurants');
    const fetchedRestaurants = await restaurantCollection
      .aggregate([
        
          $match: 
            $and: [
              
                $cond: 
                  if:  $ne: [name, ''] ,
                  then:  $text:  $search: name  ,
                  else: null,
                ,
              ,
               borough:  $in: borough  ,
               cuisine:  $in: cuisine  ,
            ],
          ,
        ]
   catch ...

我怎样才能实现它?

【问题讨论】:

【参考方案1】:

首先看你的错误MongoError: unknown top level operator: $cond,$cond是聚合表达式,需要在$and操作前使用$expr,

其次你不能在任何表达式中使用$text搜索更多关于$text restrictions的信息,我的建议是你最好在客户端检查空name条件。

【讨论】:

因此,如果我只想在某些条件下使用此模式执行某种类型的聚合操作:$expr: $cond: ...,是个好主意吗?跨度> 我尝试使用与您在答案中指定的代码相同的代码,但它显示错误消息:MongoError: Unrecognized expression '$text' 好的,是的,对不起,我忘了查看$text,可能你不能在任何表达式中使用$text,有很多restrictions,请查看。我正在寻找是否有任何解决方案,否则我会将我的答案更新到正确的方向。【参考方案2】:

所以我终于自己解决了我的代码问题。 我将聚合管道移动到另一个常量(名为aggregationPipeline)。然后,如果 name 变量不为空,我将使用数组 unshift 方法将 $text 聚合阶段添加到我的管道中。我知道这很简单,但我花了一些时间才弄清楚。这是我的代码。如果您有更好的解决方案,请发布。

const aggregationPipeline = [
    // all my others aggregation pipeline stages
  ];

  if (name)
    aggregationPipeline.unshift( $match:  $text:  $search: name   );

【讨论】:

以上是关于如何仅在特定条件下执行 MongoDB 聚合阶段之一?的主要内容,如果未能解决你的问题,请参考以下文章

如果仅在 MongoDB 中满足特定条件,则分组

mongodb Aggregation聚合操作之$facet

MongoDB 聚合管道(Aggregation Pipeline)

具有特定条件计数的 Mongodb 聚合并按输出投影的日期范围过滤不能按预期工作

Mongodb聚合$group阶段耗时较长

《MongoDB入门教程》第22篇 聚合操作