【问题标题】:Sequelize limit and offset incorrect placement in querySequelize 限制和偏移查询中的不正确位置
【发布时间】:2021-10-11 22:25:20
【问题描述】:

我在 nodeJs 中使用 sequelize,我有这个代码:

Time_Sheet_Details.findAll({
include: [
    {
        model: timesheetNotesSubcon,
        required: false,
        attributes:["note","file_name", "id", "working_hrs", "timestamp", "has_screenshot", "notes_category"]
    },
    {
        model: Timesheet,
        attributes:["id","leads_id","userid"],
        include:[
            {
                model: Lead_Info, attributes:["id","fname","lname","email","hiring_coordinator_id","status"],
                where: { hiring_coordinator_id : 326},
                include:[{
                    model: adminInfoSchema,
                    required: false,
                    attributes:["admin_id","admin_fname", "admin_lname", "admin_email", "signature_contact_nos", "signature_company"],      
                }]

            },
            {model:Personal_Info,attributes:["userid","fname","lname","email"]}
        ],
    }],
where: { 
    reference_date: filters.reference_date
},
order:[
    ["id","DESC"]
],
offset:((1-1)*30),
limit : 30,

}).then(function(foundObject){
    willFulfillDeferred.resolve(foundObject);
});

而查询结果是:

SELECT `timesheet_details`.*, `timesheet_notes_subcons`.`note` AS `timesheet_notes_subcons.note`, `timesheet_notes_subcons`.`file_name` AS `timesheet_notes_subcons.file_name`, `timesheet_notes_subcons`.`id` AS `timesheet_notes_subcons.id`, `timesheet_notes_subcons`.`working_hrs` AS `timesheet_notes_subcons.working_hrs`, `timesheet_notes_subcons`.`timestamp` AS `timesheet_notes_subcons.timestamp`, `timesheet_notes_subcons`.`has_screenshot` AS `timesheet_notes_subcons.has_screenshot`, `timesheet_notes_subcons`.`notes_category` AS `timesheet_notes_subcons.notes_category`, `timesheet.lead`.`id` AS `timesheet.lead.id`, `timesheet.lead`.`fname` AS `timesheet.lead.fname`, `timesheet.lead`.`lname` AS `timesheet.lead.lname`, `timesheet.lead`.`email` AS `timesheet.lead.email`, `timesheet.lead`.`hiring_coordinator_id` AS `timesheet.lead.hiring_coordinator_id`, `timesheet.lead`.`status` AS `timesheet.lead.status`, `timesheet.lead.admin`.`admin_id` AS `timesheet.lead.admin.admin_id`, `timesheet.lead.admin`.`admin_fname` AS `timesheet.lead.admin.admin_fname`, `timesheet.lead.admin`.`admin_lname` AS `timesheet.lead.admin.admin_lname`, `timesheet.lead.admin`.`admin_email` AS `timesheet.lead.admin.admin_email`, `timesheet.lead.admin`.`signature_contact_nos` AS `timesheet.lead.admin.signature_contact_nos`, `timesheet.lead.admin`.`signature_company` AS `timesheet.lead.admin.signature_company`, `timesheet.personal`.`userid` AS `timesheet.personal.userid`, `timesheet.personal`.`fname` AS `timesheet.personal.fname`, `timesheet.personal`.`lname` AS `timesheet.personal.lname`, `timesheet.personal`.`email` AS `timesheet.personal.email` FROM (SELECT `timesheet_details`.`id`, `timesheet_details`.`timesheet_id`, `timesheet_details`.`day`, `timesheet_details`.`total_hrs`, `timesheet_details`.`adj_hrs`, `timesheet_details`.`regular_rostered`, `timesheet_details`.`hrs_charged_to_client`, `timesheet_details`.`diff_charged_to_client`, `timesheet_details`.`hrs_to_be_subcon`, `timesheet_details`.`diff_paid_vs_adj_hrs`, `timesheet_details`.`status`, `timesheet_details`.`reference_date`, `timesheet`.`id` AS `timesheet.id`, `timesheet`.`leads_id` AS `timesheet.leads_id`, `timesheet`.`userid` AS `timesheet.userid` FROM `timesheet_details` AS `timesheet_details` LEFT OUTER JOIN `timesheet` AS `timesheet` ON `timesheet_details`.`timesheet_id` = `timesheet`.`id` WHERE (`timesheet_details`.`reference_date` >= '2016-04-23 16:00:00' AND `timesheet_details`.`reference_date` < '2017-05-02 15:59:59') ORDER BY `timesheet_details`.`id` DESC LIMIT 0, 30) AS `timesheet_details` LEFT OUTER JOIN `timesheet_notes_subcon` AS `timesheet_notes_subcons` ON `timesheet_details`.`id` = `timesheet_notes_subcons`.`timesheet_details_id` INNER JOIN `leads` AS `timesheet.lead` ON `timesheet.leads_id` = `timesheet.lead`.`id` AND `timesheet.lead`.`hiring_coordinator_id` = 326 LEFT OUTER JOIN `admin` AS `timesheet.lead.admin` ON `timesheet.lead`.`hiring_coordinator_id` = `timesheet.lead.admin`.`admin_id` LEFT OUTER JOIN `personal` AS `timesheet.personal` ON `timesheet.userid` = `timesheet.personal`.`userid` ORDER BY `timesheet_details`.`id` DESC;

如您所见,LIMIT 0, 30 不在查询的末尾。这对我来说是个问题,因为该查询不会返回任何内容,并且限制和偏移量应该在查询的末尾,如下所示:

SELECT `timesheet_details`.*, `timesheet_notes_subcons`.`note` AS `timesheet_notes_subcons.note`, `timesheet_notes_subcons`.`file_name` AS `timesheet_notes_subcons.file_name`, `timesheet_notes_subcons`.`id` AS `timesheet_notes_subcons.id`, `timesheet_notes_subcons`.`working_hrs` AS `timesheet_notes_subcons.working_hrs`, `timesheet_notes_subcons`.`timestamp` AS `timesheet_notes_subcons.timestamp`, `timesheet_notes_subcons`.`has_screenshot` AS `timesheet_notes_subcons.has_screenshot`, `timesheet_notes_subcons`.`notes_category` AS `timesheet_notes_subcons.notes_category`, `timesheet.lead`.`id` AS `timesheet.lead.id`, `timesheet.lead`.`fname` AS `timesheet.lead.fname`, `timesheet.lead`.`lname` AS `timesheet.lead.lname`, `timesheet.lead`.`email` AS `timesheet.lead.email`, `timesheet.lead`.`hiring_coordinator_id` AS `timesheet.lead.hiring_coordinator_id`, `timesheet.lead`.`status` AS `timesheet.lead.status`, `timesheet.lead.admin`.`admin_id` AS `timesheet.lead.admin.admin_id`, `timesheet.lead.admin`.`admin_fname` AS `timesheet.lead.admin.admin_fname`, `timesheet.lead.admin`.`admin_lname` AS `timesheet.lead.admin.admin_lname`, `timesheet.lead.admin`.`admin_email` AS `timesheet.lead.admin.admin_email`, `timesheet.lead.admin`.`signature_contact_nos` AS `timesheet.lead.admin.signature_contact_nos`, `timesheet.lead.admin`.`signature_company` AS `timesheet.lead.admin.signature_company`, `timesheet.personal`.`userid` AS `timesheet.personal.userid`, `timesheet.personal`.`fname` AS `timesheet.personal.fname`, `timesheet.personal`.`lname` AS `timesheet.personal.lname`, `timesheet.personal`.`email` AS `timesheet.personal.email` FROM (SELECT `timesheet_details`.`id`, `timesheet_details`.`timesheet_id`, `timesheet_details`.`day`, `timesheet_details`.`total_hrs`, `timesheet_details`.`adj_hrs`, `timesheet_details`.`regular_rostered`, `timesheet_details`.`hrs_charged_to_client`, `timesheet_details`.`diff_charged_to_client`, `timesheet_details`.`hrs_to_be_subcon`, `timesheet_details`.`diff_paid_vs_adj_hrs`, `timesheet_details`.`status`, `timesheet_details`.`reference_date`, `timesheet`.`id` AS `timesheet.id`, `timesheet`.`leads_id` AS `timesheet.leads_id`, `timesheet`.`userid` AS `timesheet.userid` FROM `timesheet_details` AS `timesheet_details` LEFT OUTER JOIN `timesheet` AS `timesheet` ON `timesheet_details`.`timesheet_id` = `timesheet`.`id` WHERE (`timesheet_details`.`reference_date` >= '2016-04-23 16:00:00' AND `timesheet_details`.`reference_date` < '2017-05-02 15:59:59') ORDER BY `timesheet_details`.`id` DESC) AS `timesheet_details` LEFT OUTER JOIN `timesheet_notes_subcon` AS `timesheet_notes_subcons` ON `timesheet_details`.`id` = `timesheet_notes_subcons`.`timesheet_details_id` INNER JOIN `leads` AS `timesheet.lead` ON `timesheet.leads_id` = `timesheet.lead`.`id` AND `timesheet.lead`.`hiring_coordinator_id` = 326 LEFT OUTER JOIN `admin` AS `timesheet.lead.admin` ON `timesheet.lead`.`hiring_coordinator_id` = `timesheet.lead.admin`.`admin_id` LEFT OUTER JOIN `personal` AS `timesheet.personal` ON `timesheet.userid` = `timesheet.personal`.`userid` ORDER BY `timesheet_details`.`id` DESC LIMIT 0, 30;

我的代码有什么地方做错了吗?我是不是放错了订单和限额?

【问题讨论】:

  • 1.您可以尝试删除include 属性吗? 2. 你说that query will return nothing是什么意思?如果您不限制结果,则查询应该返回一些东西...
  • @MariaInesParnisari 你好。感谢您的回复。无法删除包含。我需要它里面的所有属性。我的意思是它什么都不返回是因为查询结束前的限制。我需要限制在查询的末尾,而不是之前。
  • 啊哈哈我明白了,我没有看到整个结果查询。
  • 您可以在此处发布您的问题:github.com/sequelize/sequelize/issues。您更有可能得到快速响应
  • @Yassi 它为我工作

标签: javascript mysql node.js sequelize.js


【解决方案1】:

找到了我的问题的答案,我只需要添加subQuery = false,这样限制和偏移量就不会被评估到子查询中。而且offset和limit也在查询的最后。

offset:((page-1)*limit),
limit : limit,
subQuery:false

【讨论】:

    【解决方案2】:

    需要在includes之前下订单和where子句。做这样的事情

     user.findAll({
                 offset: 5, limit: 5,
                order: [
    // Will escape full_name and validate DESC against a list of valid direction parameters
    ['full_name', 'DESC']]
            }).then(function (result) {
    })
    

    结果查询将是

    如果您想在 include 中下订单,则需要在 include 部分下订单

    include: [{
                    model: taskhelpers, required: true,
                    order: {
                        order: '`updatedAt` ASC'
                    }
               }]
    

    更多详情请查看Pagination / Limiting and ordering

    更新 嵌套的 include 和 limit 和 order

    var option = {
                    offset: 5, limit: 5,
                order: [
    // Will escape full_name and validate DESC against a list of valid direction parameters
    ['id', 'DESC']],
                    attributes: [
                        'id', 'title',
                        [sequelize.Sequelize.fn('date_format', sequelize.Sequelize.col('date'), '%d-%b-%Y'), 'date']
                    ],
    
                    include: [
    
                        {
                            model: taskhelpers, required: true,
    
                            where: {
                                userId: req.params.userid,
    
                                $or: [
                                    {
                                        status: {
                                            $eq: "1"
                                        }
                                    },
                                    {
                                        status: {
                                            $eq: "3"
                                        }
                                    },
                                ]
                            }
    
                        }]
                };
    

    现在将此选项传递给您的模型参数

    tasks.findAll(options)
        .then(function (result) {
            res.send({message:result,error:null});
        })
            .catch(function (err) {
                res.send({message:null,error:err});
            })
    

    这将是生成的查询

    【讨论】:

    • 感谢您的示例,但我也尝试将限制和偏移量放在代码的开头,在此之前包括但仍然没有运气。在您的示例中,我认为它可以正常工作,因为它没有嵌套并且没有多个内部连接?
    • 在包含它们之前是否需要您的模型?
    【解决方案3】:

    遇到同样的情况,另一种方法是将数组传递给limit。

    {
    include: [
        {
            model: timesheetNotesSubcon,
            required: false,
            attributes:["note","file_name", "id", "working_hrs", "timestamp", "has_screenshot", "notes_category"]
        },
        {
            model: Timesheet,
            attributes:["id","leads_id","userid"],
            include:[
                {
                    model: Lead_Info, attributes:["id","fname","lname","email","hiring_coordinator_id","status"],
                    where: { hiring_coordinator_id : 326},
                    include:[{
                        model: adminInfoSchema,
                        required: false,
                        attributes:["admin_id","admin_fname", "admin_lname", "admin_email", "signature_contact_nos", "signature_company"],      
                    }]
    
                },
                {model:Personal_Info,attributes:["userid","fname","lname","email"]}
            ],
        }],
    where: { 
        reference_date: filters.reference_date
    },
    order:[
        ["id","DESC"]
    ],
    limit : [((page-1)*limit), limit],
    
    }
    

    【讨论】:

      【解决方案4】:

      在 Node.js 中使用 sequilize 对字段的限制、偏移、投影和全文搜索

      
              let msg = await Feedback.findAll({
                  where: Sequelize.literal('MATCH (message) AGAINST (:feedback)'), // fulltext search query
                  replacements: {
                  feedback: req.body.text  
                  },
                  attributes: ['uID', 'message'], // projection of columns
                  offset:1, // set the offset according your use case
                  limit: 1  // limit the output
              }); 
      

      【讨论】:

        【解决方案5】:

        尝试在您的请求中添加 $limit 参数,sequelize 将自动使用它 例如:“http://localhost:3031/my-service?$limit=23”

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-02-05
          • 1970-01-01
          • 2019-06-06
          • 2012-05-17
          • 1970-01-01
          • 2013-01-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多