Feathers.js Mongoose对象查询及数组长度校验问题咨询
解决Feathers.js中嵌套对象查询与数组长度校验问题
嘿,刚接触Feathers.js确实会遇到一些查询语法的小坑,我来帮你梳理这两个问题的解决方案:
1. 嵌套对象的正确查询方式
你尝试的/some-doc?obj['foo']['$eq']=1之所以无效,是因为URL中的单引号和嵌套括号格式不会被Feathers的查询解析器正确识别。Feathers遵循MongoDB风格的查询语法,但在URL参数中需要调整写法:
- 简化写法(默认匹配
$eq):直接用点符号访问嵌套字段/some-doc?obj.foo=1 - 显式指定操作符:如果需要用
$gt、$in等复杂操作符,用方括号包裹操作符/some-doc?obj.foo[$eq]=1 - 多层嵌套场景:比如
obj.inner.bar这类深层嵌套,同样沿用点符号/some-doc?obj.inner.bar=2
如果你的项目使用Feathers官方SDK(@feathersjs/client),直接在代码中写查询对象会更直观,SDK会自动处理URL编码:
app.service('some-doc').find({ query: { obj: { foo: { $eq: 1 } } } })
2. 校验数组长度大于0的两种方案
你想通过before:find hook处理的思路是可行的,只是可能逻辑细节没写对。这里提供两种可靠的实现方式:
方案一:自定义Hook转换查询参数
如果想保留checkArray=true这种自定义参数,可在hook中把它转换成数据库能识别的查询条件(以MongoDB为例):
// src/hooks/check-array-length.js module.exports = function (options = {}) { return async context => { const { query } = context.params; // 检测到自定义参数时,替换为数组非空查询 if (query.checkArray) { query.someArray = { $exists: true, $ne: [] // 确保数组存在且不为空 }; // 删除自定义参数,避免传递给数据库 delete query.checkArray; } return context; }; };
然后在服务的hook配置中注册这个钩子:
// src/services/some-doc/some-doc.hooks.js const checkArrayLength = require('../../hooks/check-array-length'); module.exports = { before: { find: [checkArrayLength()] } };
这样请求/some-doc?checkArray=true时,hook会自动将查询条件转换为someArray非空的逻辑。
方案二:直接使用数据库原生查询语法
如果不想依赖自定义参数,可直接用Feathers支持的数据库原生操作符:
- MongoDB场景:
(注:MongoDB的/some-doc?someArray[$exists]=true&someArray[$ne]=[]$size仅支持匹配固定长度,无法直接用$size[$gt]=0,所以用$ne: []更稳妥) - SQL数据库场景(以PostgreSQL为例):
由于SQL对数组的语法支持不同,可通过hook添加原生SQL条件:// SQL版本的check-array-length hook module.exports = function (options = {}) { return async context => { const { query } = context.params; if (query.checkArray) { // 用Knex添加原生SQL条件,检查数组长度大于0 context.params.knex = context.params.knex.whereRaw('array_length("someArray", 1) > 0'); delete query.checkArray; } return context; }; };
内容的提问来源于stack exchange,提问作者Yhom Torke
相关产品推荐
相关产品推荐

