Ограничение TypeORM не работает, запрос вернул один элемент в массиве независимо от того, какой предел установлен? - PullRequest
0 голосов
/ 06 августа 2020

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

код:

           await this.createQueryBuilder()
            .select(['videoComment.id', 'videoComment.comment', 'videoComment.languageCode', 'videoComment.createdAt'
                , 'video.id', 'user.id', 'user.name', 'user.profileImage'])
            .from(VideoComment, 'videoComment')
            .innerJoin('videoComment.video', 'video', ' video.id = :videoId  and video.isActive = :isActive ')
            .innerJoin('videoComment.user', 'user')
            .where(' videoComment.id > :commentId ' +
                ' and videoComment.isActive = :isActive ', {
                videoId: videoId,
                commentId: commentId,
                isActive: isActive
            })
            .orderBy('videoComment.id')
            .limit(size.valueOf())
            .getMany();

сгенерированный запрос:

SELECT "videoComment"."id"            AS "videoComment_id",
       "videoComment"."created_at"    AS "videoComment_created_at",
       "videoComment"."comment"       AS "videoComment_comment",
       "videoComment"."language_code" AS "videoComment_language_code",
       "video"."id"                   AS "video_id",
       "user"."id"                    AS "user_id",
       "user"."name"                  AS "user_name",
       "user"."profile_image"         AS "user_profile_image"
FROM "video_comment" "VideoComment",
     "video_comment" "videoComment"
         INNER JOIN "video" "video"
                    ON "video"."id" = "videoComment"."video_id" AND ("video"."id" = $1 and "video"."is_active" = $2)
         INNER JOIN "user_detail" "user" ON "user"."id" = "videoComment"."user_id"
WHERE "videoComment"."id" > $3
  and "videoComment"."is_active" = $4
ORDER BY "videoComment"."id" ASC
LIMIT 5

запрос работает нормально, когда я выполняю его на клиенте POSTGRES. Вернул желаемый результат. Но в коде приложения он возвращает только одну запись в наборе результатов.

1 Ответ

0 голосов
/ 06 августа 2020

Просматривая файл SelectQueryBuilder.ts, я обнаружил:

/**
     * Set's LIMIT - maximum number of rows to be selected.
     * NOTE that it may not work as you expect if you are using joins.
     * If you want to implement pagination, and you are having join in your query,
     * then use instead take method instead.
     */
    limit(limit?: number): this;

Итак, я использовал функцию .take. Он дает правильный результат, но генерирует один дополнительный запрос.

SELECT DISTINCT "distinctAlias"."videoComment_id" as "ids_videoComment_id", "distinctAlias"."videoComment_id"
FROM (SELECT "videoComment"."id"            AS "videoComment_id",
             "videoComment"."created_at"    AS "videoComment_created_at",
             "videoComment"."comment"       AS "videoComment_comment",
             "videoComment"."language_code" AS "videoComment_language_code",
             "video"."id"                   AS "video_id",
             "user"."id"                    AS "user_id",
             "user"."name"                  AS "user_name",
             "user"."profile_image"         AS "user_profile_image"
      FROM "video_comment" "VideoComment",
           "video_comment" "videoComment"
               INNER JOIN "video" "video" ON "video"."id" = "videoComment"."video_id" AND
                                             ("video"."id" = $1 and "video"."is_active" = $2)
               INNER JOIN "user_detail" "user" ON "user"."id" = "videoComment"."user_id"
      WHERE "videoComment"."id" > $3
        and "videoComment"."is_active" = $4) "distinctAlias"
ORDER BY "distinctAlias"."videoComment_id" ASC, "videoComment_id" ASC
LIMIT 5
    
SELECT "videoComment"."id"            AS "videoComment_id",
       "videoComment"."created_at"    AS "videoComment_created_at",
       "videoComment"."comment"       AS "videoComment_comment",
       "videoComment"."language_code" AS "videoComment_language_code",
       "video"."id"                   AS "video_id",
       "user"."id"                    AS "user_id",
       "user"."name"                  AS "user_name",
       "user"."profile_image"         AS "user_profile_image"
FROM "video_comment" "VideoComment",
     "video_comment" "videoComment"
         INNER JOIN "video" "video"
                    ON "video"."id" = "videoComment"."video_id" AND ("video"."id" = $1 and "video"."is_active" = $2)
         INNER JOIN "user_detail" "user" ON "user"."id" = "videoComment"."user_id"
WHERE ("videoComment"."id" > $3 and "videoComment"."is_active" = $4)
  AND "videoComment"."id" IN ($5, $6, $7, $8, $9)
ORDER BY "videoComment"."id" ASC

Сначала он получает отдельные идентификаторы, а затем использует эти идентификаторы для получения фактического запрошенного набора результатов. Это кажется менее эффективным, поскольку выполняется один дополнительный запрос, но проблема решается.

...