CNode

【已解决】使用mongoose的find查询集合,怎么定义别名,如_id映射成id

问答
Wwazsq发布于8 年前最后回复8 年前16 回复7119 浏览0 收藏

问题描述 查询时需要将主键返回给客户端,使用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)

W
wazsq#1·8 年前
引用 GitHuber-lucopy id as id, haha

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

W
wazsq#2·8 年前
引用 AnzerWall我记得是有查询hook用那个在查询后改

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

G
GitHuber-lu#3·8 年前

copy _id as id, haha

A
AnzerWall#4·8 年前

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

L
ldcsirtest2012#5·8 年前

$project

L
ldcsirtest2012#6·8 年前

Project:{_id:newid}

W
wazsq#7·8 年前
引用 ldcsirtest2012Project:{ id:newid}

@ldcsirtest2012 emmmm,没看懂呢

来自酷炫的 CNodeMD

L
lovegnep#8·8 年前
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);
}
});
W
wazsq#10·8 年前
引用 lovegnepdocs = Model.Testmodel.aggregate([ { $match:query//匹配条件 }, { $project:{ id:"$ id"//将 id映射成id }} ...

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

L
lovegnep#11·8 年前
引用 wazsq@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){
}
R
rrbe#13·8 年前

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

A
AnzerWall#15·8 年前
引用 wazsq@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));

W
wazsq#16·8 年前
参与回复
登录后即可参与回复。登录