Как выполнить запрос во включенном массиве объектов в Sequelize, используя nodeJS - PullRequest
1 голос
/ 25 мая 2020

У меня 2 таблицы.

  • Users таблица, в которой хранится моя пользовательская информация.
  • Expertises таблица, хранящая поля экспертиз. (например: «Строительство», «Программирование» и т. д. c ..)

У каждого пользователя есть уникальный идентификатор, и у каждого опыта также есть уникальный идентификатор.

каждый пользователь в моей таблице может быть несколько «экспертиз». Существует таблица «многие ко многим», соединяющая пользователей и их опыт, под названием UsersExpertises.

В таблице UsersExpertises я сохраняю userId и expertiseId, и когда я хочу получить все экспертизы конкретного c пользователя. Я могу просто запросить его ID и получить его экспертизу. Я использую для этого Sequelize include.

Все, что я только что объяснил, до сих пор работает потрясающе. Моя проблема:

Мне нужно добавить функцию поиска в свое приложение, чтобы наши пользователи могли искать других пользователей, мой алгоритм поиска выполняет поиск в нескольких столбцах в таблице пользователей, а также один из параметров поиска должен включать их опыт .. Итак, если кто-то набирает «Программирование», что является названием опыта, мне нужно вернуть список всех пользователей, которые обладают этим опытом.

Итак, запрос where, который я пока что:

const where = {
        [Op.and]: [
            // Only search for active user profiles.
            { isActive: true },
            // Make sure we filter our searching user from the results
            { id: { [Op.ne]: userId } }
        ],
        [Op.or]: [

            // Search user by their first and last names
            { firstName: { [Op.substring]: keyword } },
            { lastName: { [Op.substring]: keyword } },
            Sequelize.where(Sequelize.fn('concat', Sequelize.col('firstName'), ' ', Sequelize.col('lastName')), {
                [Op.substring]: keyword
            }),

            // Search business name and description.
            { businessName: { [Op.substring]: keyword } },
            { businessDescription: { [Op.substring]: keyword } },

            // Search in expertises and cities.
            // { '$expertises.name$': { [Op.substring]: keyword } }, // TODO - This doesn't work.
            { '$city.name$': { [Op.substring]: keyword } }
        ]
    };

И это окончательный результат (если это имеет значение):

{
    "id": 35,
    "firstName": "David",
    "lastName": "Hasslehoff",
    "city": {
        "id": 4,
        "name": "Los Angeles"
    },
    "expertises": [
        {
            "id": 1,
            "name": "Construction"
        },
        {
            "id": 2,
            "name": "Programming"
        }
    ]
}

Взгляните на эту строку: { '$city.name$': { [Op.substring]: keyword } }

City - это объект, который я включаю в таблицу User в этом запросе, это отлично работает, поскольку City - это объект, который может быть привязан к пользователю только с одним городом, но User может иметь несколько Expertise, поэтому включенные Expertise s представляют собой массив Expertise объектов.

Как я могу выполнить поиск «имени» «Экспертиза» внутри моего включенного массива? Можно ли это сделать?

Надеюсь, я включил всю необходимую информацию, чтобы вы все поняли мою проблему, если чего-то не хватает, сообщите мне, и я предоставлю вам все необходимое.

Заранее большое спасибо!

1 Ответ

1 голос
/ 27 мая 2020

После получения комментариев по поводу Sequelize.literal от @Anatoly, мне удалось найти решение.

Спасибо, Анатолий.

На случай, если у кого-то есть похожее выпуск в будущем, прикрепляю свой код:

            {
                [Op.or]: Sequelize.literal(`EXISTS(
                    SELECT EF.id, EF.name FROM UsersExpertises AS UE
                    JOIN ExpertiseFields AS EF
                    ON EF.id = UE.expertiseId
                    WHERE UE.userId = User.id
                    AND EF.name LIKE '%${keyword}%')`)
            }
...