You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Datatables结合Node.js、Elasticsearch实现时服务器端分页失效问题

问题原因

  1. 响应字段错误:返回给Datatables的data字段是全量ES查询结果,没有做分页切片,导致所有数据都被渲染到同一页
  2. 参数类型不符合规范:recordsFiltered要求是数字类型,代表过滤后的总记录数,原有代码中将其赋值为切片后的数组,不符合Datatables服务端模式的响应规则
  3. 缺少分页偏移参数:服务端模式下Datatables会传递start参数代表当前页的起始索引,原有代码只获取了每页条数length,没有按偏移量截取对应页的数据

修复代码

1. 修复Controller逻辑(临时解决方案,适合数据量小于1万的场景)

var elasticDataModel = require('../model/getDataElastic');

exports.getData = function (req, res) {
    elasticDataModel(function (elasticList) {
        const draw = parseInt(req.body.draw)
        // 读取Datatables传递的分页参数
        const start = parseInt(req.body.start) || 0
        const pageSize = parseInt(req.body.length) || 20
        // 无搜索逻辑时过滤后总条数等于总记录数
        const recordsTotal = elasticList.length
        const recordsFiltered = elasticList.length
        // 截取当前页对应的数据
        const pageData = elasticList.slice(start, start + pageSize)

        const data = JSON.stringify({
            "data": pageData,
            "draw": draw,
            "recordsTotal": recordsTotal,
            "recordsFiltered": recordsFiltered
        });
        res.send(data);
    });
}

2. 全量优化方案(适合数据量大于1万的场景,直接从ES做分页查询减少内存占用)

首先修改Model层,支持接收分页参数:

const { Client } = require('@elastic/elasticsearch')

const client = new Client({
    node: '',
    auth: {
        username: '',
        password: ''
    }
})
// 新增from、size参数接收分页条件,同时返回总记录数
module.exports = function getElasticData(callback, from = 0, size = 20) {
    client.search({
        index: 'anomalies02_bhc-lstm2',
        from: from,
        size: size,
        body: {
            query: {
                match_all: {}
            }
        }
    }, function (error, response, status) {
        if (error) {
            console.log("search error: " + error)
            return callback([], 0)
        }
        if (response) {
            const elasticList = response.body.hits.hits.map(hit => hit)
            // 同时返回当前页数据和总条数
            callback(elasticList, response.body.hits.total.value);
        } else {
            console.log("<p>No results</p>");
            callback([], 0)
        }
    });
}

再修改对应的Controller逻辑:

var elasticDataModel = require('../model/getDataElastic');

exports.getData = function (req, res) {
    const draw = parseInt(req.body.draw)
    const start = parseInt(req.body.start) || 0
    const pageSize = parseInt(req.body.length) || 20
    // 直接将分页参数传给ES,查询对应页的数据
    elasticDataModel(function (pageData, total) {
        const recordsTotal = total
        const recordsFiltered = total

        const data = JSON.stringify({
            "data": pageData,
            "draw": draw,
            "recordsTotal": recordsTotal,
            "recordsFiltered": recordsFiltered
        });
        res.send(data);
    }, start, pageSize)
}

内容的提问来源于stack exchange,提问作者GhostyIs1337

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 09:24:03