如何将 SQLite 查询转换为 MongoDB 查询

Posted

技术标签:

【中文标题】如何将 SQLite 查询转换为 MongoDB 查询【英文标题】:How to convert SQLite query into MongoDB query 【发布时间】:2021-02-13 01:19:16 【问题描述】:

如何使用聚合框架将此 SQLite 查询转换为 MongoDB 查询

SQLite 查询:

"
FROM car
    WHERE (@make is NULL OR @make = make)
    AND (@model is NULL OR @model = model)
    AND (@minPrice is NULL OR @minPrice <= price)
    AND (@maxPrice is NULL OR @maxPrice >= price)
"

我试图转换成 mongodb 聚合名作 一切都按预期运行

[
  
    $match: 
      $and: [
         $or: [ make: null ,  make: "BMW" ] ,
         $or: [ model: null ,  model: "320" ] ,
         $or: [ price: null ,  price:  $gte: 1000  ] ,
         $or: [ price: null ,  price:  $lte: 80000  ] ,
      ],
    ,
  ,
   $project:  _id: 0, make: 1, model: 1, price: 1  ,
];

但是当不匹配“make”时,它什么也不返回

[
  
    $match: 
      $and: [
         $or: [ make: null ,  make: "asds" ] ,
         $or: [ model: null ,  model: "320" ] ,
         $or: [ price: null ,  price:  $gte: 1000  ] ,
         $or: [ price: null ,  price:  $lte: 80000  ] ,
      ],
    ,
  ,
   $project:  _id: 0, make: 1, model: 1, price: 1  ,
];

【问题讨论】:

以下是将 SQL 转换为聚合查询的指南:SQL to Aggregation Mapping Chart。 非常感谢我尝试转换并且一切都按预期工作但是当“make”不匹配时它什么也不返回 【参考方案1】:

我通过将 field: null 替换为 field: $exists: &lt;false&gt; || &lt;true&gt; 解决了这个问题

详细显示 mongodb $exists operator

所以我有这个“汽车”系列

[
 make: 'Audi', model: 'A2', price: 13999,
 make: 'BMW', model: '116', price: 12999,
 make: 'BMW', model: 'X1', price: 18999,
 make: 'BMW', model: '320', price: 24000,
 make: 'BMW', model: '320', price: 50999,
 make: 'Ford', model: 'Fiesta', price: 14999,
 make: 'Mazda', model: '6', price: 13999,
 make: 'Merces-Benz', model: '200', price: 38999,
 make: 'Mazda', model: '6', price: 16999,
 make: 'Mazda', model: 'e250', price: 11999,
]

如果我搜索一下

    make = '宝马' model = 'asd'(我们的 db 集合中未提供值) minPrice = 1000 maxPrice = 40000

将返回此结果

 make: 'BMW', model: '116', price: 12999,
 make: 'BMW', model: 'X1', price: 18999,
 make: 'BMW', model: '320', price: 24000,

没有这个“价格 = 50999”的文档

make: 'BMW', model: '320', price: 50999

这意味着“价格”条件也有效

让我们编写这个聚合代码

我有一个管道,它有两个阶段“$match”和“$project”

const pipeline = [
  
    $match: 
      $and: [
         $or: [ make:  $exists: false  ,  make: "BMW" ] ,
         $or: [ model:  $exists: true  ,  model: "asd" ] ,
         $or: [ price:  $exists: false  ,  price:  $gte: 1000  ] ,
         $or: [ price:  $exists: false  ,  price:  $lte: 50000  ] ,
      ],
    ,
  ,
   $project:  _id: 0, make: 1, model: 1, price: 1  ,
];

在这种“$or”条件下

 $or: [ make:  $exists: false  ,  make: "BMW" ] 

将检查“make”字段是否存在。

如果不存在 ($exists: false) 将继续到 "$or" 运算符中的下一个条件,如果为 true 将继续到 '$and 中的下一个 "$or" 条件' 运算符,

如果存在 ($exists: true) 只会继续到 '$and' 运算符中的下一个 "$or" 条件,依此类推。

【讨论】:

以上是关于如何将 SQLite 查询转换为 MongoDB 查询的主要内容,如果未能解决你的问题,请参考以下文章

如何将sql查询转换为mongodb查询中的exists

如何将此类 sql 查询转换为 mongodb 查询

如何将 MongoDB 查询转换为 JSON?

如何将 SQL 查询转换为 MongoDB

如何将 NOT (A AND B) 转换为 mongodb 查询

如何将其转换为 mongodb 聚合查询?