Есть ли в mongo функция, позволяющая определить, существует ли элемент в массиве?

#javascript #node.js #mongodb #mongoose #mongodb-query

Вопрос:

Я пытаюсь написать запрос таким образом, чтобы определенная строка не существовала в массиве. Моя схема такова:

     _id: {
        type: String,
        required: true
    },
    ...
    meta: {
        user_likes: {
            type: [String],
        },
        user_dislikes: {
            type: [String],
        },
        user_liked_by: {
            type: [String],
        },
        user_matches: {
            type: [String],
        },
    ...
    },
 

Содержимое массивов в meta объекте в _id ключе других документов, который имеет тип String .

Теперь у меня есть конечная точка API для обработки этого запроса, которая выглядит примерно так:

 router.post('/fetchUsersForClient', async function (req, res) {
    /* Body
    {
        "client_id" : String
    }
    */
    try {
            var client_id = req.body.client_id;
            const users = await SampleUser.find(); //query here
            res.json(users);
        }
        
    } catch (error) {
        res.send({ message: error });
    }
});
 

Я хочу написать запрос таким образом, чтобы переменная client_id не существовала ни в одном из массивов meta объекта и client_id не была равна _id ни одному документу.

ИЗМЕНИТЬ: Я попытался использовать этот запрос для получения своих результатов, но я не знаю, как заменить "1" в запросе.

 {
    "_id" : {
        $ne : "1"
    },
    $and : [
        {
            "meta.user_likes" : {
                $not : /.*1.*/i
            }
        },
        {
            "meta.user_dislikes" : {
                $not : /.*1.*/i
            }
        },
        {
            "meta.user_matches" : {
                $not : /.*1.*/i
            }
        } 
    ]
}
 

Комментарии:

1. просто попробуй { "_id": { $ne: client_id }, "meta.client_id": { $ne: client_id } }

2. @turivishal это не работает, я думаю, потому client_id что в meta объекте нет

Ответ №1:

Я нашел ответ на эту проблему, немного изменив приведенный код. Здесь я использовал отдельную константу для инициализации шаблона регулярного выражения. Вот мой подход:

 router.post('/fetchUsersForClient', async function (req, res) {
    /* Body
    {
        "client_id" : String
    }
    */
    try {
            var client_id = req.body.client_id;
            var expr = '.*var.*'
            expr = expr.replace("var", client_id);
            const chkExp = new RegExp(expr);
            const users = await User.find(
                {
                    "_id": {
                        $ne: client_id
                    },
                    $and: [
                        {
                            "meta.user_likes": {
                                $not: chkExp
                            }
                        },
                        {
                            "meta.user_liked_by": {
                                $not: chkExp
                            }
                        },
                        {
                            "meta.user_dislikes": {
                                $not: chkExp
                            }
                        },
                        {
                            "meta.user_matches": {
                                $not: chkExp
                            }
                        }
                    ]
                }
            );
            res.json(users);
    } catch (error) {
        console.log(error);
        res.send({ message: error });
    }
});