【已解决】使用mongoose的find查询集合,怎么定义别名,如_id映射成id
发布于 6 年前 作者 wazsq 5583 次浏览 来自 问答

问题描述 查询时需要将主键返回给客户端,使用mongoose默认的_id,但是不太符合我们团队的习惯,想把_id重名民为id,又不能改变数据库的结构。 单条查询还可以直接修改,但是多条查询就有点痛苦的。感觉mongoose应该有这个功能,但是找了半天没找到,大佬们有知道的还望告知。

示例代码

	Role.find({}).limit(param.page_size).skip(param.page_no - 1)

解决方案 多谢各位大佬的回复,尤其是 @lovegnep ,自己的问题已经基本解决,贴上代码

	// service处理
	find(param: object | any): Promise<any> {
        const _para: any = paramMapByArr(param, ['role_id', 'user_name', 'status', 'tel', 'qq', 'wechart', 'professional_class', 'credit_rating']);
        // return User.find(_para).limit(param.page_size).skip(param.page_no - 1);
        return User.aggregate([
            {
                $match: _para
            },
            {
                $limit: param.page_size
            },
            {
                $skip: param.page_no - 1
            },
            {
                $project: {
                    id: '$_id',
                    _id: '$-',
                    user_name: '$user_name',
                    login_ip: '$login_ip',
                    // ...
                }
            }
        ]).exec();
    }
	
	// controller
	async find(ctx: BaseContext, next: any) {
        // 判断权限

        // 参数
        const param = ctx.request.body;
        param.page_size = param.page_size || 10;
        param.page_no = param.page_no > 0 ? param.page_no : 1;
        try {
			// 自动扫描注入
            const user = await service.user.find(param);
            ctx.rest(user);
        } catch (err) {
            ctx.body = { code: 1, message: err.message };
        }
    },	

向各位大佬敬礼

16 回复

copy _id as id, haha

我记得是有查询hook用那个在查询后改

@GitHuber-lu 允许你小小的皮一下Q(^)Q

@AnzerWall 可能是我英语不好的缘故,一直没找到Qrz…

Project:{_id:newid}

@ldcsirtest2012 emmmm,没看懂呢

来自酷炫的 CNodeMD

docs = Model.Testmodel.aggregate([
		{
			$match:query//匹配条件
		},
	{
		$project:{
			id:"$_id"//将_id映射成id
	}}

]).sort('-id').limit(5).exec(function(err,data){
if(err){
	console.log(err);
}else{
	console.log(data);
}
});

@lovegnep 多谢朋友,我立马试试

@lovegnep 谢谢大佬,可以解决我的问题,但是没法使用promise的catch方法来捕获异常,你们有什么建议的吗

@wazsq 你试试下面这样做可以不,我没试过。

Model.Testmodel.aggregate([
		{
			$match:query//匹配条件
		},
	{
		$project:{
			id:"$_id"//将_id映射成id
	}}

]).sort('-id').limit(5).exec().then(function(res){}).catch(function(err){})

我一般都是用async/await来做的

try{
let res = await Model.Testmodel.aggregate().exec()
}catch(err){
}

@lovegnep 用try{}catch语句是可以的,谢谢大佬,学到了,:)

find 直接用 aggregate 替换了不太好吧…… 楼上说的 hook 指的应该是 middleware,有 pre hook 和 post hook. 你可以看下 post(‘find’, funtion (result) {}) mongoose-middleware

@rrbe 好的,谢谢您的回复,我下午回去看下

来自酷炫的 CNodeMD

@wazsq

rrbe 理解得没错 http://mongoosejs.com/docs/middleware.html

mongoose支持在每次查询后对查询出来的结果做处理,也就是post hook或者说middleware。。。

不建议用aggregate去代替find仅仅是为了一次改名,太暴力了,对mongodb负担挺大,你这么干迟早会被你们老大打死,mongodb的aggregate性能再高也终归没find快。。

面向模式debug而其他不管不顾不可取

收回我用hook的话,这里可以直接使用mongoose提供的变换函数选项即可,不用上hook…

====================

'use strict';

const mongoose = require('mongoose');
const { Schema } = mongoose;
const TestSchema = new Schema( {
    message: String
});
TestSchema.options.toObject = {
    transform(doc, ret, options) {
        ret.id = doc.id;
        delete ret._id;
        return ret;
    }
};
const TestModel = mongoose.model('Test',TestSchema);

mongoose.connect('mongodb://127.0.0.1/test');

(async function main() {
    const ret = await TestModel.find();
    console.log(ret);
    console.log(JSON.stringify(ret));

})().then(_ => process.exit(0));

@AnzerWall 谢谢大佬,我记住了,我明天去试试,哈哈哈,再次拜谢

来自酷炫的 CNodeMD

回到顶部