草庐IT

javascript - 有条件地包括聚合管道阶段

coder 2023-10-30 原文

我有一个函数可以根据给定的参数给我一些订单。 但是,参数可以为空,在那种情况下我想单独留下 $match

这是我目前拥有的代码:

if(req.query.status && typeof(req.query.status) == 'array'){
        var match = {
            $in: req.query.status
        };
    }else if(req.query.status){
        var match = req.query.status;
    }else{
        //when empty find all statuses
        var match = null;
    }


 Order.aggregate(
    {
        $match: {
            'shop.nameSlug' : req.query.nameSlug,
        }
    },
    {
        $unwind: "$status"
    },
    {
        $match: {
            "status.status" : match
        }
    },
    {
        $group: {
            _id: "$_id",
            status: {
                $addToSet: "$status"
            },
            number: {
                $first: "$number"
            },
            date: {
                $first: "$date"
            },
            comment: {
                $first: "$comment"
            }
        }
    }
).exec(function(err, orders){
})

match 为 null 时,没有订单返回,因为 mongo 正在搜索等于 null 的字段。当 match == null 时,如何删除 $match

最佳答案

您的意思是根据提供的选项构建整个管道。毕竟它只是一个数据结构。

您还错误地测试了“数组”,您应该使用 instanceof因为typeof实际上会返回 "object" 而不是 "array"

此外,除了在 $unwind 之后添加之外,您确实希望在 first 管道阶段中的条件也能优化选择文档。在需要的地方:

var pipeline = [
  { $match: 
      Object.assign(
        { 'shop.nameSlug' : req.query.nameSlug },
        (req.query.status) 
          ? { "status.status": (req.query.status instanceof Array)
            ? { "$in": req.query.status } : req.query.status }
          : {}
      )
  },
  { $unwind: "$status" },
  ...(
    (req.query.status)
      ? [{ "$match": { 
          "status.status": (req.query.status instanceof Array)
           ? { "$in": req.query.status } : req.query.status
       }}]
      : []
    ),
    { $group: {
      _id: "$_id",
      status: { $addToSet: "$status" },
      number: { $first: "$number" },
      date: { $first: "$date" },
      comment: { $first: "$comment" }
    }}
];    


Order.aggregate(pipeline).exec(function(err, orders){

})

给定一个 req 对象,其中包含 status 中的内容,您将获得:

// Example stucture
var req = {
  query: { 
   nameSlug: "Bill", 
   status: "A"
  },
};

// Pipeline output as:

[
    {
        "$match" : {
            "shop.nameSlug" : "Bill",
            "status.status" : "A"
        }
    },
    {
        "$unwind" : "$status"
    },
    {
        "$match" : {
            "status.status" : "A"
        }
    },
    {
        "$group" : {
            "_id" : "$_id",
            "status" : {
                "$addToSet" : "$status"
            },
            "number" : {
                "$first" : "$number"
            },
            "date" : {
                "$first" : "$date"
            },
            "comment" : {
                "$first" : "$comment"
            }
        }
    }
]

使用数组:

var req = {
  query: { 
   nameSlug: "Bill", 
   status: ["A","B"]
  },
};

// Pipeline output as:
[
    {
        "$match" : {
            "shop.nameSlug" : "Bill",
            "status.status" : {
                "$in" : [ 
                    "A", 
                    "B"
                ]
            }
        }
    },
    {
        "$unwind" : "$status"
    },
    {
        "$match" : {
            "status.status" : {
                "$in" : [ 
                    "A", 
                    "B"
                ]
            }
        }
    },
    {
        "$group" : {
            "_id" : "$_id",
            "status" : {
                "$addToSet" : "$status"
            },
            "number" : {
                "$first" : "$number"
            },
            "date" : {
                "$first" : "$date"
            },
            "comment" : {
                "$first" : "$comment"
            }
        }
    }
]

什么都没有:

var req = {
  query: { 
   nameSlug: "Bill", 
   //status: ["A","B"]
  },
};

// Pipeline output as:
[
    {
        "$match" : {
            "shop.nameSlug" : "Bill"
        }
    },
    {
        "$unwind" : "$status"
    },
    {
        "$group" : {
            "_id" : "$_id",
            "status" : {
                "$addToSet" : "$status"
            },
            "number" : {
                "$first" : "$number"
            },
            "date" : {
                "$first" : "$date"
            },
            "comment" : {
                "$first" : "$comment"
            }
        }
    }
]

因此您可以根据提供的值查看有条件地包含哪些部分。


使用 $filter

你真的应该使用 $filter在这里。它比 $unwind 效率高很多你真的没有分组任何东西。您真正想要的只是过滤数组。这就是您有条件添加的所有内容:

var pipeline = [
  { $match: 
      Object.assign(
        { 'shop.nameSlug' : req.query.nameSlug },
        (req.query.status) 
          ? { "status.status": (req.query.status instanceof Array)
            ? { "$in": req.query.status } : req.query.status }
          : {}
      )
  },
  ...(
    (req.query.status)
      ? [{ "$addFields": { 
          "status": {
            "$filter": {
              "input": "$status",
              "cond": {
                [(req.query.status instanceof Array) ? "$in" : "$eq"]:
                  [ "$$this.status", req.query.status ]
              }
            }    
          }
       }}]
      : []
    )
];

$in之间的选择和 $eq用于比较测试,具体取决于提供的内容。您可以选择将整个内容包装在 $setUnion 中如果您“真的”想在结果中使用“集合”。但通常看起来您只是想从数组中“过滤”出值。

对单一值的相同期望:

var req = {
  query: { 
   nameSlug: "Bill", 
   //status: ["A","B"]
   status: "A"
  },
};

/* 1 */
[
    {
        "$match" : {
            "shop.nameSlug" : "Bill",
            "status.status" : "A"
        }
    },
    {
        "$addFields" : {
            "status" : {
                "$filter" : {
                    "input" : "$status",
                    "cond" : {
                        "$eq" : [ 
                            "$$this.status", 
                            "A"
                        ]
                    }
                }
            }
        }
    }
]

数组:

var req = {
  query: { 
   nameSlug: "Bill", 
   status: ["A","B"]
  },
};

/* 1 */
[
    {
        "$match" : {
            "shop.nameSlug" : "Bill",
            "status.status" : {
                "$in" : [ 
                    "A", 
                    "B"
                ]
            }
        }
    },
    {
        "$addFields" : {
            "status" : {
                "$filter" : {
                    "input" : "$status",
                    "cond" : {
                        "$in" : [ 
                            "$$this.status", 
                            [ 
                                "A", 
                                "B"
                            ]
                        ]
                    }
                }
            }
        }
    }
]

或者什么都没有:

var req = {
  query: { 
   nameSlug: "Bill", 
   //status: ["A","B"]
  },
};

/* 1 */
[
    {
        "$match" : {
            "shop.nameSlug" : "Bill"
        }
    }
]

如果您不需要过滤,则只需删除额外的管道阶段。

关于javascript - 有条件地包括聚合管道阶段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46362486/

有关javascript - 有条件地包括聚合管道阶段的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  3. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  4. ruby-on-rails - 使用包含多个关联和单独的条件 - 2

    我的Gallery模型中有以下查询:media_items.includes(:photo,:video).rank(:position_in_gallery)我的图库模型有_许多媒体项,每个都有一个照片或视频关联。到目前为止,一切正常。它返回所有media_items包括它们的photo或video关联,由media_item的position_in_gallery属性排序。但是我现在需要将此查询返回的照片限制为仅具有is_processing属性的照片,即nil。是否可以进行相同的查询,但条件是返回的照片等同于:.where(photo:'photo.is_processingIS

  5. ruby-on-rails - 在 haml View 中重构条件 - 2

    除了可访问性标准不鼓励使用这一事实指向当前页面的链接,我应该怎么做重构以下View代码?#navigation%ul.tabbed-ifcurrent_page?(new_profile_path)%li{:class=>"current_page_item"}=link_tot("new_profile"),new_profile_path-else%li=link_tot("new_profile"),new_profile_path-ifcurrent_page?(profiles_path)%li{:class=>"current_page_item"}=link_tot("p

  6. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  7. ruby-on-rails - 在具有 ActiveRecord 条件的相关模型中按字段排序 - 2

    我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我

  8. ruby - 如何在 ruby​​ 中复制目录结构,不包括某些文件扩展名 - 2

    我想编写一个ruby​​脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"

  9. ruby - 如果满足给定条件,则结束 ruby​​ 程序 - 2

    基本上,我只是试图在满足特定条件时停止程序运行其余行。unlessraw_information.firstputs"Noresultswerereturnedforthatquery"breakend然而,在程序运行之前我得到了这个错误:Invalidbreakcompileerror(SyntaxError)执行此操作的正确方法是什么? 最佳答案 abort("Noresultswerereturnedforthatquery")unlesscondition或unlessconditionabort("Noresultswer

  10. ruby-on-rails - 如果条件与 &&,是否有任何性能提升 - 2

    如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:

随机推荐