我如何使用 MongoDB 聚合来有条件地匹配搜索表单中不为空的字段?

How can i use MongoDB aggregation to conditionally match fields from a search form that aren't null?

我的网站上有一个带有 10 多个可选搜索参数的大型搜索表单。我需要 return 来自 MongoDB 的所有文档,这些文档与每次搜索中出现的任何表单字段相匹配。

实现预期结果的一种方法是按顺序为每个可能的非空搜索字段组合编写 if else 语句,但必须有更好的方法。

    ex.
    const sQ = new TMDLs(request.body);


    }else if(sQ.Basin && sQ.Water_Body_Name && sQ.Water_Body_ID){
        searchData = await TMDLs.aggregate([
            { $match: { $text: {$search: `\"${sQ.Basin}\"`}}},
            { $match: { Water_Body_Name: sQ.Water_Body_Name}},
            { $match: { Water_Body_ID: sQ.Water_Body_ID}}

        ]);
    }else if(sQ.Basin && sQ.Water_Body_Name){
        searchData = await TMDLs.aggregate([
            { $match: { Basin: sQ.Basin }},
            { $match: {Water_Body_Name: sQ.Water_Body_Name}}
        ]);

上面的代码有效,但尝试非空搜索参数的每个组合是不切实际的。我需要聚合结果 return 所有匹配非空搜索字段的记录。

我尝试了 $ifNull、$exists、$group、$project 和许多其他条件运算符,但找不到任何可以解决此问题的方法。

构造此问题的一种方法是列出所有搜索并过滤掉 non-null 个:

const criteria = [
            sQ.Basin != null && { $text: {$search: `\"${sQ.Basin}\"`}}},
            sQ.Water_Body_Name != null && { Water_Body_Name: sQ.Water_Body_Name}},
            sQ.Water_Body_ID != null && { $match: { Water_Body_ID: sQ.Water_Body_ID}}
            sQ.Basin != null && { Basin: sQ.Basin },
            ...
].filter(Boolean)

获得这些条件后,您可以使用 $and 将它们组合成一个 $match 阶段(相当于多个串行 $match 阶段)。

TMDLs.aggregate([
  {$match: {$and: criteria}},
  ...
])