如何修改我的mongodb / mongoose查询,以便它采用对象数组而不是字符串数组?

时间:2017-01-03 10:41:18

标签: node.js mongodb mongoose

在我的应用中,我有一个评论架构:

var CommentsSchema = new Schema({
    user_id: {type: String, required: true, ref: 'users'},
    text_content: {type: String},
    is_anonymous: {type: Boolean, default: false}
});

现在我正在构建mongoose查询以下载所有评论并将其显示给用户。

由于我不想从最终用户阻止的用户下载帖子,因此我介绍了从被阻止的作者中排除帖子的可能性:

var blockedUsers = req.body.blockedUsers;

function withBlockedUsers(query, blockedUsers) {
    if(blockedUsers != undefined){
        query.$and.push({ 'user_id' : { $nin: blockedUsers } });
    }

    return query;
}

var query = {};
query.$and = [];

query = withBlockedUsers(query, blockedUsers)
...
query = Comment.find(query);

query.exec(function(err, comments){
        if(err) {
            callback(err);
            return;
        }
    return callback(null, comments);
    });

该代码有效,当我调用我的终端时,我需要发送一个string被阻止的用户ID数组,并且他们的帖子将被排除。

现在我正在更改我的功能,而不是传递string被阻止的用户数组我传递了一些对象:

{ 
 user_id: '586af425378c19fc044aa85f'
 is_anonymous: '0' 
},

我不想在满足这两个条件时从这些用户下载帖子。

例如,当我在我的应用中有两个帖子时:

{
    user_id: '586af425378c19fc044aa85f',
    text_content: 'text1',
    is_anonymous: true
},
{
    user_id: '586af425378c19fc044aa85f', //same as above
    text_content: 'text2',
    is_anonymous: false
}

我传递blockedUsers对象:

{ 
 user_id: '586af425378c19fc044aa85f'
 is_anonymous: '0' 
},

作为回报,我只需要显示:

{
    user_id: '586af425378c19fc044aa85f',
    text_content: 'text1',
    is_anonymous: true
},

应阻止其他帖子,因为user_id已被识别且is_anonymousfalse

使用我当前的代码我收到错误:

  

消息:'对于值" [object Object]"转换为字符串失败在路上   " user_id"',名称:' CastError',kind:' string',value:{        user_id:' 586af425378c19fc044aa85f',        is_anonymous:' 0' },path:' user_id',reason:undefined}对于值" [object Object]"转换为字符串失败在路径" user_id"

1 个答案:

答案 0 :(得分:1)

您需要一种方法来构建一个使用 $nor 运算符的查询,该运算符对一个或多个查询表达式的数组以及所有失败的文档执行逻辑NOR运算返回数组中的查询表达式。

例如,当您传递像

这样的对象数组时
var blockedUsers = [
    {
        user_id: '586af425378c19fc044aa85f'
        is_anonymous: '0' 
    },
    {
        user_id: '585808969e39db5196444c06'
        is_anonymous: '0' 
    },
    {
        user_id: '585808969e39db5196444c07'
        is_anonymous: '0' 
    }
]

您的查询应该从根本上结束为

Comment.find({
    "$nor": [
        {
            user_id: '586af425378c19fc044aa85f'
            is_anonymous: false 
        },
        {
            user_id: '585808969e39db5196444c06'
            is_anonymous: false
        },
        {
            user_id: '585808969e39db5196444c07'
            is_anonymous: false 
        }
    ]
}).exec(function(err, comments){
    if(err) {
        callback(err);
        return;
    }
    return callback(null, comments);
});

所以任务是转换像

这样的东西
var blockedUsers = [
    {
        user_id: '586af425378c19fc044aa85f'
        is_anonymous: '0' 
    },
    {
        user_id: '585808969e39db5196444c06'
        is_anonymous: '0' 
    },
    {
        user_id: '585808969e39db5196444c07'
        is_anonymous: '0' 
    }
]

var query = {
    "$nor": [
        {
            user_id: '586af425378c19fc044aa85f'
            is_anonymous: false 
        },
        {
            user_id: '585808969e39db5196444c06'
            is_anonymous: false
        },
        {
            user_id: '585808969e39db5196444c07'
            is_anonymous: false 
        }
    ]
}

由于您传入的是一组对象,因此您可以使用 map() 方法将is_anonymous值转换为布尔值,以便您的重构函数看起来像:

function withBlockedUsers(query, blockedUsers) {
    var norOperator = [];
    if(blockedUsers != undefined){
        norOperator = blockedUsers.map(function(user){
            return {
                "user_id": user.user_id,
                "is_anonymous": (user.is_anonymous === '1')
            }
        });
        query["$nor"] = norOperator;
    }
    return query;
}