【问题标题】:Using knex SELECT query results for another SELECT query将 knex SELECT 查询结果用于另一个 SELECT 查询
【发布时间】:2017-04-22 19:45:37
【问题描述】:

我正在尝试使用 Knex 运行 PostgreSQL 查询,然后使用结果运行另一个查询。

exports.buildBuoyFeaturesJSON = function (conditionA, conditionB) {
var query = null;

var selectedFields = knex.select
(
    knex.raw('t_record.id AS id'),
    ...
    knex.raw('t_record.latitude AS latitude'),
    knex.raw('t_record.longitude AS longitude')
)
    .from('t_record')
    .then(function (response) {
        var geometry_array = [];
        var rows = response.rows;
        var keys = [];

        for (var key = 0; key <= rows.length - 1; key++) {
            var geometry =
                {
                    "id" : rows[key].id,
                    "type" : "Feature",
                    "geometry" : rows[key].geometry,
                    "properties" : {
                        ...
                        "sensors" : []
                    }
                };
            keys.push(rows[key].id);
            geometry_array.push(geometry);
        }
        getMeasurementsAndSensors(keys, geometry_array);
    });
};

后一个函数使用前一个函数的一些结果。由于 Knex 的异步特性,我需要从第一个函数的 .then() 语句中调用第二个函数:

function getMeasurementsAndSensors (keys, geometry_array) {
        var query = knex
            .select
            (
                't_record_id',
                'i_sensor_id',
                'description',
                'i_measurement_id',
                't_sensor_name',
                't_measurement_name',
                'value',
                'units'
            )
            .from('i_record')
            ...
            .whereRaw('i_record.t_record_id IN (' + keys + ')')
            .orderByRaw('t_record_id, i_sensor_id ASC')
            .then(function (response) {

        var rows = response.rows;
        var t_record_id = 0;
        var i_sensor_id = 0;
        var record_counter = -1;
        var sensor_counter = -1;

        for (var records = 0; records <= rows.length -1; records++) {
            if (t_record_id !== rows[records].t_record_id) {
                t_record_id = rows[records].t_record_id;
                record_counter++;
                sensor_counter = -1;
            }

            if (i_sensor_id !== rows[records].i_sensor_id) {
                i_sensor_id = rows[records].i_sensor_id;

                geometry_array[record_counter].properties.sensors[++sensor_counter] =
                {
                    'i_sensor_id' : rows[records].i_sensor_id,
                    't_sensor_name' : rows[records].t_sensor_name,
                    'description' : rows[records].description,
                    'measurements' : []
                };
            }

            geometry_array[record_counter].properties.sensors[sensor_counter].measurements.push
            ({
                    'i_measurement_id': rows[records].i_measurement_id,
                    'measurement_name': rows[records].t_measurement_name,
                    'value': rows[records].value,
                    'units': rows[records].units
            });
        }
        //wrapping features with metadata.
        var feature_collection = GEOGRAPHY_METADATA;
        feature_collection.features = geometry_array;

        JSONToFile(feature_collection, 'buoy_features');
    });

}

目前我将最终结果保存到 JSON 文件,因为我无法让 Promises 工作。 JSON 稍后用于驱动小型 OpenLayers 应用程序,因此在获得结果后进行 JSON 化。

我很确定从数据库中获取数据,将其保存到文件,然后从另一个进程访问它并将其用于 OpenLayers 是一种非常多余的方法,但到目前为止,它是唯一一种作品。 我知道有很多方法可以使这些功能更好地工作,但我对 Promise 很陌生,不知道如何在大多数基本功能之外使用它们。欢迎任何关于如何改进此代码的建议。

【问题讨论】:

  • knex 的关键在于避免执行原始查询,而您完全违背了这一点,从而放弃了使用knex 的所有好处。对于原始查询执行,pg-promise 会更适合 ;)
  • 当我学会如何正确使用它时,我会尽量减少查询的原始性。

标签: node.js postgresql promise openlayers-3 knex.js


【解决方案1】:

你似乎缺少的只是一堆回报。

这是两个函数的骨架化版本,包括必要的返回:

exports.buildBuoyFeaturesJSON = function(conditionA, conditionB) {
    return knex.select (...)
    ^^^^^^
    .from(...)
    .then(function(response) {
        // synchronous stuff
        // synchronous stuff
        return getMeasurementsAndSensors(keys, geometry_array);
        ^^^^^^
    }).then(function(geometry_array) {
        var feature_collection = GEOGRAPHY_METADATA;
        feature_collection.features = geometry_array;
        return feature_collection;
        ^^^^^^
    });
};

function getMeasurementsAndSensors(keys, geometry_array) {
    return knex.select(...)
    ^^^^^^
    .from(...)
    ...
    .whereRaw(...)
    .orderByRaw(...)
    .then(function(response) {
        // heaps of synchronous stuff
        // heaps of synchronous stuff
        // heaps of synchronous stuff
        return geometry_array;
        ^^^^^^^^^^^^^^^^^^^^^
    });
}

我将feature_collection 集合部分移到buildBuoyFeaturesJSON() 中,因为它似乎更符合逻辑。如果没有,那么将其移回getMeasurementsAndSensors() 将非常简单。

我没有尝试修复@vitaly-t 强调的其他问题。

【讨论】:

  • 这很棒!我知道有什么东西不见了,但不知道是什么。谢谢!
  • 谢谢!在 knex 调用之前,我错过了“返回”,无法弄清楚为什么事情不起作用。
猜你喜欢
  • 1970-01-01
  • 2018-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-01
  • 2021-03-02
相关资源
最近更新 更多