上代码,下面的 id 字段 和 status 字段,如果前端没有传过来这个字段,那就 去掉筛选 或 者查询全部。这块应该怎么写?
const findList = await userModel
// mongoose 的查找方法
.find({
nickname: { $regex: nicknameReg },
_id: id ? ObjectId(id) : '查询字段的所有状态 或者 不查询这个字段, 这块需要怎么写?',
status: status ? status : '查询字段的所有状态 或者 不查询这个字段, 这块需要怎么写?'
})
1
indo 2021-09-19 21:29:51 +08:00 via iPhone 1
我的想法应该是在函数入口加下判断,是否有入参,有责用入参,没有则空。
|
2
dream4ever 2021-09-19 23:45:05 +08:00 2
```js
const query = { nickname: { $regex: nicknameReg } } if (id) { query._id = ObjectId(id) } if (status) { query.status = status } const findList = await userModel.find(query) ``` |
3
tukon479 2021-09-21 19:31:29 +08:00
用 $and 和 $or 就行了
`{ $and: [ { $or: [_id ? {_id}: {}] } , { $or: [ status ? {status} : {} ] } ] }` |
4
ChangJingli 2021-11-09 11:03:32 +08:00
@dream4ever 目前 where 条件都是这么写的,条件多的时候感觉很不优雅
|
5
dream4ever 2021-11-09 21:03:36 +08:00
@ChangJingli 忽然想到其实可以把这个常用的需求封装成一个方法,做一层抽象,用起来就能“优雅”一点了
|
6
ChangJingli 2021-11-10 09:46:31 +08:00
@dream4ever 提取到 service 层仍是这样拼 where 条件;我尝试过封装公共 util 过滤条件,然而发现过滤条件跟业务有强耦合,util 不知道你什么时候需要保留空字符串,什么时候不需要,`null`类型 亦如此。
|
7
ouxch 2021-12-31 15:00:26 +08:00
最笨的办法当然就是写几个条件分支来组装最终的查询条件,例如:
```javascript const filter = { nickname: { $regex: nicknameReg } } if (!!id) fiter._id = ObjectId(id) if (!!status) fiter.status = status const findList = await userModel.find(filter) ``` --- 其实这是一个如何让编码更加优雅的问题,不只适用于此处你这个问题,如果从事`JavaScript`开发,建议了解下函数式编程,这里以函数式编程库 [ramda]( https://ramda.cn/) 为例,看看写出来又是怎样的: <br/> 首先定义一个通用的纯函数 `omitNil` ```javascript const { reject, isNil } = require('ramda') const omitNil = reject(isNil) ``` 做个解释: `isNil` 和 `reject` 都是 **ramda** 直接提供的函数,并且 **ramda** 的函数都是自动柯里化的; `isNil` 的作用:检测输入值是否为 `null` 或 `undefined`; `reject` 的作用:可视为 `filter` 的补操作,简言之 `filter` 是留下满足条件的元素、`reject` 是排除满足条件的元素; 将 `reject` 和 `isNil` 进行组合,得到 `omitNil` 函数,它的作用是:排除掉值为 `null` 或 `undefined` 的元素 做一个简单直观的测试,看看 `omitNil` 函数的作用: ```javascript const obj = { a: 1, b: null, c: undefined } omitNil(obj) // => { a: 1 } obj // => { a: 1, b: null, c: undefined } const arr = [1, null, undefined] omitNil(arr) // => [ 1 ] arr // => [1, null, undefined] ``` 可以看到,`omitNil` 的返回值和输入参数相比,少了值为 `null` 或 `undefined` 的元素,并且没有修改原输入参数 <br/> **现在回到楼主的问题**,就可以一行代码实现了: ```javascript const findList = await userModel.find(omitNil({ nickname: { $regex: nicknameReg }, _id: id, status })) ``` <br/> 最后,**ramda** 的核心设计理念就包含了:数据不变性和函数无副作用,因此以上纯函数均不会改变输入参数的值。 <br/> > 参考: > > https://ramda.cn > > https://ramdajs.com/ |