我正在使用融合版Platform 5.4.1的社区版。我没有找到任何CLI命令来打印KSQL Server版本,但是当我输入KSQL时,可以在所附的屏幕截图中找到。
我有一个地理围栏表-
CREATE TABLE GEOFENCE (GEOFENCEID INT,
FLEETID VARCHAR,
GEOFENCECOORDINATES VARCHAR)
WITH (KAFKA_TOPIC='MONGODB-GEOFENCE',
VALUE_FORMAT='JSON',
KEY= 'GEOFENCEID');
每当从REST API支持的Web应用程序对geofence MongoDB集合执行插入或更新操作时,数据就会从Kafka MongoDB源连接器发送到Geofence KSQL表。将地理围栏制成表格的想法是,由于表格是可变的,因此它将保存更新的地理围栏信息,并且由于插入或更新操作不会非常频繁,并且只要在Geofence MongoDB集合中发生更改,它们就会在Geofence KSQL上进行更新表格,因为这里的键是GeofenceId。
我有车辆位置的实时直播-
CREATE STREAM VEHICLE_POSITION (VEHICLEID INT,
FLEETID VARCHAR,
LATITUDE DOUBLE,
LONGITUDE DOUBLE)
WITH (KAFKA_TOPIC='VEHICLE_POSITION',
VALUE_FORMAT='JSON')
我想像这样加入表和流-
CREATE STREAM VEHICLE_DISTANCE_FROM_GEOFENCE AS
SELECT GF.GEOFENCEID,
GF.FLEETID,
VP.VEHICLEID,
GEOFENCE_UDF(GF.GEOFENCECOORDINATES, VP.LATITUDE, VP.LONGITUDE)
FROM GEOFENCE GF
LEFT JOIN VEHICLE_POSITION VP
ON GF.FLEETID = VP.FLEETID;
但是KSQL不允许我这样做,因为我正在对非行键列的FLEETID
执行连接。尽管这在SQL中是可能的,但是如何在KSQL中实现呢?
注意:根据我的应用程序的业务逻辑,Fleet Id用于组合地理围栏和属于车队的车辆。
表的样本数据-
INSERT INTO GEOFENCE
(GEOFENCEID INT, FLEETID VARCHAR, GEOFENCECOORDINATES VARCHAR)
VALUES (10, 123abc, 52.4497_13.3096);
流的样本数据-
INSERT INTO VEHICLE_POSITION
(VEHICLEID INT, FLEETID VARCHAR, LATITUDE DOUBLE, LONGITUDE DOUBLE)
VALUES (1289, 125abc, 57.7774, 12.7811):
答案 0 :(得分:0)
要解决您的问题,您需要的是FENCEID到GEOFENCECOORDINATES的表。您可以使用这样的表加入VEHICLE_POSITION流,以获得所需的结果。
那么,如何获取FENCEID表到GEOFENCECOORDINATES?
简单的答案是您不能使用当前表定义!您声明该表仅具有GEOFENCEID
作为主键。然而,FleetId可以有很多栅栏。为了能够对此进行模式设置,GEOFENCEID
和FENCEID
都需要成为表主键的一部分。
考虑示例:
INSERT INTO GEOFENCE VALUES (10, 'fleet-1', 'coords-1');
INSERT INTO GEOFENCE VALUES (10, 'fleet-2', 'coords-2');
在运行这两个插入时,表将仅包含一行,键为10
,值为'fleet-2', 'coords-2'
。
即使我们能以某种方式在表中捕获上述信息,也请考虑一下该主题中是否存在逻辑删除,该怎么办,因为第一行已从源Mongo表中删除。逻辑删除是键(10
)和null
值。然后,ksqlDB将使用键10
从其表中删除该行,从而留下一个空表。
这是您问题的症结所在!
首先,您需要配置源连接器,以将围栏ID和车队ID都放入消息的密钥中。
接下来,您需要在ksqlDB中访问它。不幸的是,尽管很快this is being worked on,但ksqlDB从0.10.0 / CP 6.0.0版本开始不支持多个键列。
同时,如果您的密钥是包含两个密钥字段的JSON文档,例如
{
"GEOFENCEID": 10,
"FLEETID": "fleet-1"
}
然后您可以将其作为STRING导入到ksqlDB中:
-- 5.4.1 syntax:
-- ROWKEY will contain the JSON document, containing GEOFENCEID and FLEETID
CREATE TABLE GEOFENCE (
GEOFENCECOORDINATES VARCHAR
)
WITH (
KAFKA_TOPIC='MONGODB-GEOFENCE',
VALUE_FORMAT='JSON'
);
-- 6.0.0 syntax:
CREATE TABLE GEOFENCE (
JSONKEY STRING PRIMARY KEY,
GEOFENCECOORDINATES VARCHAR
)
WITH (
KAFKA_TOPIC='MONGODB-GEOFENCE',
VALUE_FORMAT='JSON'
);
现在正确定义了表,您可以使用EXTRACTJSONFIELD
访问JSON密钥中的数据,并使用COLLECT_SET
收集所有围栅坐标。我不是100%肯定会在5.4.1上使用(请参阅您的操作方法),但不会在6.0.0上使用。
-- 6.0.0 syntax
CREATE TABLE FLEET_COORDS AS
SELECT
EXTRACTJSONFIELD(JSONKEY, '$.FLEETID') AS FLEETID,
COLLECT_SET(GEOFENCECOORDINATES)
FROM GEOFENCE
GROUP BY EXTRACTJSONFIELD(JSONKEY, '$.FLEETID');
这将为您提供一个FleetId表,用于一组围栏坐标。您可以使用它来加入车辆位置流。当然,您的GEOFENCE_UDF
udf将需要接受ARRAY<STRING>
作为篱笆坐标,因为可能有很多。
祝你好运!