我有一个简单的REST API,我想在特定端点上实现过滤。
想象一下,我有一个这样的端点:
localhost:5000/api/items?color="red"
处理这样的请求:
const items = await Items.find({color: req.query.color})
当color
参数存在时,此方法有效。但是,如果省略color
参数,则查询会搜索color
为undefined
的项目。这不是我需要的行为。
在我的情况下,我想添加多个过滤器参数,如果它们不存在则会被忽略。我是否必须为每种情况创建一个单独的查询,或者是否有一个选项告诉Mongoose不搜索字段(在这种情况下为color
),如果它为null或未定义?
答案 0 :(得分:5)
您可以使用“destructuring assignment”在req.query中解压缩变量。
const { color } = req.query;
if(color) {
const items = await Items.find({ color })
}
如果您有多个过滤器,则可以使用上面的变量。例如,您可能有color
和type
个参数。这样,您可以构建一个对象以传递给find方法。
const { color, type } = req.query;
let query = {};
if(color) {
query.color = color;
}
if(type) {
query.type = type;
}
const items = await Items.find(query);
如果color
或type
不在原始查询中,则它们将未定义或falsy,因此将跳过该参数的if语句。
希望它有效!
答案 1 :(得分:5)
我刚刚遇到同样的问题,如果你使用ES6支持的节点版本,你应该可以使用spread。它会自动处理未定义的
var filters = {
colour: "red",
size: undefined
}
Items.find({...filters})
// only colour is defined, so it becomes
Items.find({colour:"red"})
注意如果您使用的是Babel。您可能需要先定义一个对象。
var query = {...filters}
Items.find(query)
答案 2 :(得分:1)
在传递对象之前,您可以从对象中删除未定义的键。
Object.keys(filter).forEach(key => filter[key] === undefined && delete filter[key])
将上述代码放入util中,并在各处重复使用。
答案 3 :(得分:1)
如 francisct 所述,您可以通过在连接选项中使用 ignoreUndefined
来实现这一点,而无需执行任何手动检查:
const mongoose = require('mongoose');
mongoose.connect(mongoDb, { ignoreUndefined: true });
或者,您可以使用 reduce
将您在查询中查找的选项显式指定为数组,并仅使用不是 undefined
的字段构造过滤器对象:>
const query = { color: 'red', price: 2, hello: 'world' };
const fields = ['color', 'price', 'size'];
function getFilter(query, fields) {
return fields.reduce((filter, field) => {
if (query[field] !== undefined)
return {
[field]: query[field],
...filter,
};
return filter;
}, {});
}
const filter = getFilter(query, fields); // { price: 2, color: 'red' }
在这种情况下,函数不会向对象添加“hello”字段,因为“hello”不在数组中。它还忽略“大小”,因为它不在查询中。您可以像这样使用返回的对象:
const items = await Items.find(filter);
您可以使用隐式返回和三元运算符来缩短此函数:
const getFilter = (query, fields) => fields.reduce(
(filter, field) => query[field] !== undefined ? {
[field]: query[field],
...filter,
} : filter, {}
);
很酷,但可读性较差。
答案 4 :(得分:0)
连接到 MongoDB 时,您可以在连接选项中使用 ignoreUndefined
,以便在您的查询中,所有未定义的键在序列化为 BJSON 时都会被跳过。您可以在此 page