【问题标题】:How to convert SQLite query into MongoDB query如何将 SQLite 查询转换为 MongoDB 查询
【发布时间】: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”不匹配时它什么也不返回

标签: javascript database mongodb mongoose aggregation-framework


【解决方案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},
]

如果我搜索一下

  1. make = '宝马'
  2. model = 'asd'(我们的 db 集合中未提供值)
  3. minPrice = 1000
  4. 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" 条件,依此类推。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 2011-05-23
    相关资源
    最近更新 更多