如何使用 mongodb 架构实现自定义过滤器?

How to implement a custom filter with mongodb schema?

我想知道是否可以实施任何方法来为复杂搜索设置自定义过滤器?

例如,

User.someMethodName((eachUser) => {
   const temp = eachUser.temperature;
   if(temp.mesure === 'C' && temp.value > 36) return true;
   if(temp.mesure === 'F' && convertToCel(temp.value) > 36) return true;
   return false;
})

像这样。我知道我可以 await User.find({}) 并在其上使用数组过滤方法进行过滤,但我担心的是,在那种情况下,我将无法进行我可以用 mongoose 进行的分页limit(), skip() 方法。

如有任何帮助,我们将不胜感激。谢谢!

编辑:刚刚发现可以使用带有 $redact 的聚合来实现此目的,但仍未弄清楚如何实现它来满足此需求。

您可以使用 $switch 聚合框架运算符。

https://docs.mongodb.com/manual/reference/operator/aggregation/switch/#example

根据您的要求,这里有一个例子

示例文档

每个案例一份文件

{
  "name" : "sensor1",
  "measure" : "C",
  "value" : 36 
}

{
  "name" : "sensor2",
  "measure" : "F",
  "value" : 78
}

{
  "name" : "sensor3",
  "measure" : "C",
  "value" : 12
}

{
  "name" : "sensor4",
  "measure" : "F",
  "value" : 113
}

查询

使用不同的案例,您可以根据度量和值涵盖所有场景。


  • 在大小写运算符中设置了华氏度公式。
  • 如果需要,添加您的排序运算符和其他匹配条件。
  • $skip$limit 可以使用代码动态设置

db.test.aggregate(
[{$project : { 
 "name" : 1, 
 "measure": 1,
 "value": 1,
 "result" :
 { $switch:
    {
       branches: [
          { 
          //when your Celsius temp is greater and equals to 36
          case: { $and : [ { $eq : [ "$measure" , "C" ] },
                           { $gte : [ "$value" , 36 ] } ] },
          then: true    
          },
          { 
          //when your Celsius temp is less then 36
          case: { $and : [ { $eq : [ "$measure" , "C" ] },
                           { $lt : [ "$value" , 36 ] } ] },
          then: false
          },
          { 
          //when your Fahrenheit temp is greater and equals to 36
          case: { $and : [ { $eq : [ "$measure" , "F" ] },
                            { $gte : [ {"$multiply" : [ { "$sum": 
                                       ["$value", -32]}, 5/9]} , 36 ] } ] },
          },
          then: true    
          },
          { 
          //when your Fahrenheit temp is less than 36
          case: { $and : [ { $eq : [ "$measure" , "F" ] },
                           { $lt  : [ {"$multiply" : [ { "$sum": 
                                    ["$value", -32]}, 5/9]} , 36 ] } ] }, ] },
          then: false    
          }
       ],
       default: "error"
    }
}}},
{$skip : 0},
{$limit : 2}])

结果

{
  "name" : "sensor1",
  "measure" : "C",
  "value" : 36,
  "result" : true
}
{
  "name" : "sensor2",
  "measure" : "F",
  "value" : 78,
  "result" : false
}