Elasticsearch ES|QL 地理空间索引加入纽约犯罪地图

可以根据地理空间数据连接两个索引。在本教程中,我将向你展示如何通过混合邻里多边形和 GPS 犯罪事件坐标来创建纽约市的犯罪地图。
安装
如果你还没有安装好自己的 Elasticsearch 及 Kibana 的话,请参考如下的链接来进行安装。
-
如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch
-
Kibana:如何在 Linux,MacOS 及 Windows 上安装 Elastic 栈中的 Kibana
在第一次启动 Elasticsearch 时,我们需要记下超级用户 elastic 的密码:

这个密码将在下面进行使用。
装载测试数据
定义映射
我们在 Kibana 中打入如下的命令来定义索引 nyc_neighborhood 及 crime_events
PUT nyc_neighborhood
{"mappings": {"properties": {"neighborhood": {"type": "keyword"},"borough": {"type": "keyword"},"location": {"type": "geo_shape"}}}
}
我们也可以在命令行中使用如下的命令来进行操作:
curl -k -XPUT -u elastic:<YourPassword> "https://localhost:9200/nyc_neighborhood" -H "Content-Type: application/json" -d'
{"mappings": {"properties": {"neighborhood": {"type": "keyword"},"borough": {"type": "keyword"},"location": {"type": "geo_shape"}}}
}'
PUT crime_events
{"mappings": {"properties": {"crime_type": {"type": "keyword"},"crime_timestamp": {"type": "date"},"crime_location": {"type": "geo_point"}}}
}
我们也可以在命令行中使用如下的命令来进行操作:
curl -k -u elastic:<YourPassword> -XPUT "https://localhost:9200/crime_events" -H "Content-Type: application/json" -d'
{"mappings": {"properties": {"crime_type": { "type": "keyword" },"crime_timestamp": { "type": "date" },"crime_location": { "type": "geo_point" }}}
}'
如果你想删除上面的两个索引,你可以在命令行中进行如下的操作:
curl -k -u elastic:<YourPassword> -XDELETE "https://localhost:9200/nyc_neighborhood"curl -k -u elastic:<YourPassword> -XDELETE "https://localhost:9200/crime_events"
注意:请注意 geo_shape 和 geo_point 字段类型用于位置。因为邻里是区域,所以应该通过多边形表示,而犯罪事件是地点,因此是单个点。
我们可以注意到上面的两个索引有两个位置字段:crime_location 是 geo_point 数据类型,而另外一个 location 是 geo_shape 类型。

如上所示,如果一个 geo_point 被一个 geo shape 所包含,那么这两个数据就是关联的。我们可以正对它们进行数据的丰富。我们可以从另外一个索引中得到额外的字段,比如,neighborhood。这样我们可以针对整个 neighborhood 进行数据的统计和可视化。
批量加载 - bulk load
我为邻域准备了详细数据,其中包含约 600 行,因此我不会在这里列出,而是请使用 bulk API 将其加载到 ELK。
从 IPFS 进行下载
我们使用如下的命令来进行下载:
docker run --rm -it \
-v "$PWD:/tmp" \
-e IPFS_GATEWAY="https://ipfs.filebase.io/" \
curlimages/curl:8.5.0 --parallel --output "/tmp/#1.json" "ipfs://{QmaZD1xzi1MFf2MhjrZv7U2BGKji9U1jRB9im1MbbPG446,QmNNaC9AquYsQfRu5nqZgWcCjFKEAqv2XS1XgHw3Tut8ck}"
$ docker run --rm -it \
> -v "$PWD:/tmp" \
> -e IPFS_GATEWAY="https://ipfs.filebase.io/" \
> curlimages/curl:8.5.0 --parallel --output "/tmp/#1.json" "ipfs://{QmaZD1xzi1MFf2MhjrZv7U2BGKji9U1jRB9im1MbbPG446,QmNNaC9AquYsQfRu5nqZgWcCjFKEAqv2XS1XgHw3Tut8ck}"
Unable to find image 'curlimages/curl:8.5.0' locally
8.5.0: Pulling from curlimages/curl
c30352492317: Pull complete
90f58e8ca393: Pull complete
4ca545ee6d5d: Pull complete
Digest: sha256:08e466006f0860e54fc299378de998935333e0e130a15f6f98482e9f8dab3058
Status: Downloaded newer image for curlimages/curl:8.5.0
DL% UL% Dled Uled Xfers Live Total Current Left Speed
100 -- 507k 0 2 0 0:00:02 0:00:02 --:--:-- 226k
$ ls
QmNNaC9AquYsQfRu5nqZgWcCjFKEAqv2XS1XgHw3Tut8ck.json QmaZD1xzi1MFf2MhjrZv7U2BGKji9U1jRB9im1MbbPG446.json
我们使用如下的命令来进行重新命名:
mv QmaZD1xzi1MFf2MhjrZv7U2BGKji9U1jRB9im1MbbPG446.json nyc_neighborhood_bulk.jsonmv QmNNaC9AquYsQfRu5nqZgWcCjFKEAqv2XS1XgHw3Tut8ck.json crime_events.json
$ ls
crime_events.json nyc_neighborhood_bulk.json
crime_events.json 文件展示:
"index": {}}
{"crime_type": "theft", "timestamp": "2024-07-24T10:00:00Z", "crime_location": {"type": "point", "coordinates": [-74.0060, 40.7128]}}
{"index": {}}
{"crime_type": "assault", "timestamp": "2024-07-24T12:30:00Z", "crime_location": {"type": "point", "coordinates": [-73.9890, 40.6892]}}
{"index": {}}
{"crime_type": "vandalism", "timestamp": "2024-07-24T15:45:00Z", "crime_location": {"type": "point", "coordinates": [-73.9106, 40.7769]}}
{"index": {}}
{"crime_type": "robbery", "timestamp": "2024-07-25T09:15:00Z", "crime_location": {"type": "point", "coordinates": [-73.9865, 40.7306]}}
nyc_neighborhood_bulk 文件展示:
{"index": {}}
{"neighborhood": "Allerton", "borough": "Bronx", "location": {"type": "Polygon", "coordinates": [[[-73.86888180915341, 40.857223150158326], [-73.86831755272824, 40.85786206225831], [-73.86955371467232, 40.85778409560018], [-73.87102485762065, 40.857309948816905], [-73.87048054998716, 40.865413584098484], [-73.87055489856489, 40.86970279858986], [-73.86721594442561, 40.86968966363671], [-73.85745, 40.86953300000018], [-73.85555000000011, 40.871813000000145], [-73.85359796757658, 40.8732883686742], [-73.84859700000018, 40.871670000000115], [-73.84582253683678, 40.870239076236174], [-73.85455918463374, 40.85995383576425], [-73.85466543306826, 40.859585694988056], [-73.85638870335896, 40.85759363530448], [-73.86888180915341, 40.857223150158326]]]}}
{"index": {}}
上传文件至 Elasticsearch
curl -XPOST -u elastic:<YourPassword> "https://localhost:9200/nyc_neighborhood/_bulk" -H "Content-Type: application/json" -k --data-binary "@nyc_neighborhood_bulk.json" > /dev/nullcurl -XPOST -u elastic:<YourPassword> "https://localhost:9200/crime_events/_bulk" -H "Content-Type: application/json" -k --data-binary "@crime_events.json" > /dev/null
curl -XPOST -u elastic:LX+LGtCWdSa9zn1d2Ebs "https://localhost:9200/nyc_neighborhood/_bulk" -H "Content-Type: application/json" -k --data-binary "@nyc_neighborhood_bulk.json" > /dev/null% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed
100 561k 0 58846 100 504k 251k 2211k --:--:-- --:--:-- --:--:-- 2463k
我们可以到 Kibana 中进行查看:

我们看到有32个文档已经写入到 Elasticsearch 中。
curl -XPOST -u elastic:LX+LGtCWdSa9zn1d2Ebs "https://localhost:9200/crime_events/_bulk" -H "Content-Type: application/json" -k --data-binary "@crime_events.json" > /dev/null% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed
100 6809 0 3805 100 3004 27552 21752 --:--:-- --:--:-- --:--:-- 49340
我们到 Kibana 中进行查看:

我们可以看到有 20 个文档写入到 Elasticsearch 中。
我们也可以在 Kibana 中使用 ES|QL 来展示数据:
POST /_query?format=csv
{"query": """from nyc_neighborhood"""
}

加入地理空间数据集
丰富策略
在 Elasticsearch 世界中,它被称为丰富。你将创建丰富策略,该策略将定义包含键值对的查找表
PUT /_enrich/policy/what-is-area-name
{"geo_match": {"indices": "nyc_neighborhood","match_field": "location","enrich_fields": ["neighborhood" , "borough"]}
}
上面的意思表明,如果 location 字段包含另外一个索引中的 geo_point 点,那么 neighborhood 及 borough 将会被丰富。
它将从 nyc_neighborhood 索引中获取字段。match field 是关键,而 enrich_fields 将是附加到索引的值,你将来会通过 enrich 处理器或 ES|QL 命令来丰富这些值。
创建策略后,你必须执行它:
POST _enrich/policy/what-is-area-name/_execute
这是使用选定数据创建新的系统索引。你可以使用 ES|QL 显示其中的内容。
POST _query?format=csv
{"query":"""from .enrich-what-is-area-name*| limit 1000"""
}
这是你的查找表。从现在起,你可以使用它执行连接。
使用 ES|QL 连接数据
以下查询将汇总每个地区的犯罪事件。
POST /_query?format=txt
{"query": """from crime_events| keep crime_type,timestamp,crime_location| enrich what-is-area-name on crime_location| where borough is not null| limit 10"""
}

POST /_query?format=txt
{"query": """from crime_events| keep crime_type,timestamp,crime_location| enrich what-is-area-name on crime_location| where borough is not null| stats howMany = count(*) by borough,crime_type| limit 10"""
}

上面真的每个 borough 地区进行了统计。
Kibana 中的可视化
请使用 Maps 创建图层并制作漂亮的仪表板。添加图层时,你可以使用 ES|QL 获取正确的数据。首先来创建 Data views:



我们下面来做可视化:




在上面,我们使用如下的查询:
from crime_events | keep crime_location | limit 10000


我们放大地图就可以看到显示的数据。
按照同样的方法,我们添加另外一个 layer,使用如下的查询:
from nyc_neighborhood | keep location | limit 10000

我们需要调整上下层(通过拖拽调整层的关系)。最终我们得到上面的可视化图。
相关文章:
Elasticsearch ES|QL 地理空间索引加入纽约犯罪地图
可以根据地理空间数据连接两个索引。在本教程中,我将向你展示如何通过混合邻里多边形和 GPS 犯罪事件坐标来创建纽约市的犯罪地图。 安装 如果你还没有安装好自己的 Elasticsearch 及 Kibana 的话,请参考如下的链接来进行安装。 如何在 Linux࿰…...
csp-j知识点:联合(Union)的基本概念
一、联合(Union)的基本概念 联合是C/C语言中一种特殊的数据结构,它的主要特点是所有成员共享同一块内存空间。这意味着在任何给定时刻,联合中只有一个成员是有效的,因为它们都占用相同的物理内存位置。联合的大小取决…...
docker-compose 方式安装部署confluence
一、confluence简介 Confluence是一款由澳大利亚软件公司Atlassian开发的企业协作工具。它是一个基于web的团队协作平台,用于帮助团队成员共享和协同工作的知识、文档、想法和项目。 Confluence提供了一个集中管理和共享文档、知识库和项目信息的平台。团队成员可…...
深入理解计算机系统阅读笔记-第十二章
第12章 网络编程 12.1 客户端-服务器编程模型 每个网络应用都是基于客户端-服务器模型的。根据这个模型,一个应用时由一个服务器进程和一个或者多个客户端进程组成。服务器管理某种资源,并且通过操作这种资源来为它的客户端提供某种服务。例如…...
网络原理(九):数据链路层 - 以太网协议 应用层 - DNS 协议
目录 1. 数据链路层 1.1 以太网协议 1.1.1 以太网帧格式 1.2 mac 地址 1.2.1 IP 地址和 mac 地址的区别 1.3 帧中的类型字段 1.3.1 MTU - 最长载荷长度 1.3.2 ARP 协议 2. DNS 协议 1. 数据链路层 数据链路层, 是一个底层的层次, 主要用于交换机开发, 对于 Java 开发…...
rtthread学习笔记系列(4/5/6/7/15/16)
文章目录 4. 杂项4.1 检查是否否是2的幂 5. 预编译命令void类型和rt_noreturn类型的区别 6.map文件分析7.汇编.s文件7.1 汇编指令7.1.1 BX7.1.2 LR链接寄存器7.1.4 []的作用7.1.4 简单的指令 7.2 MSR7.3 PRIMASK寄存器7.4.中断启用禁用7.3 HardFault_Handler 15 ARM指针寄存器1…...
【拒绝算法PUA】3065. 超过阈值的最少操作数 I
系列文章目录 【拒绝算法PUA】0x00-位运算 【拒绝算法PUA】0x01- 区间比较技巧 【拒绝算法PUA】0x02- 区间合并技巧 【拒绝算法PUA】0x03 - LeetCode 排序类型刷题 【拒绝算法PUA】LeetCode每日一题系列刷题汇总-2025年持续刷新中 C刷题技巧总结: [温习C/C]0x04 刷…...
今日总结 2025-01-14
学习目标 掌握运用 VSCode 开发 uni - app 的配置流程。学会将配置完善的项目作为模板上传至 Git,实现复用。项目启动 创建项目:借助 Vue - Cli 方式创建项目,推荐从国内地址 https://gitee.com/dcloud/uni - preset - vue/repository/archiv…...
关于扫描模型 拓扑 和 传递贴图工作流笔记
关于MAYA拓扑和传递贴图的操作笔记 一、拓扑低模: 1、拓扑工作区位置: 1、准备出 目标 高模。 (高模的状态如上 ↑ )。 2、打开顶点吸附,和建模工具区,选择四边形绘制. 2、拓扑快捷键使…...
C#知识|泛型Generic概念与方法
哈喽,你好啊,我是雷工! 关于泛型在前面学习记录过 《泛型集合List相关方法》、《Dictionary泛型集合的使用总结》; 其中泛型集合 List<T>、Dictionary<k,v>所在的命名空间为:System.Collection.Generic…...
centos 8 中安装Docker
注:本次样式安装使用的是centos8 操作系统。 1、镜像下载 具体的镜像下载地址各位可以去官网下载,选择适合你们的下载即可! 1、CentOS官方下载地址:https://vault.centos.org/ 2、阿里云开源镜像站下载:centos安装包…...
vscode vue 自动格式化
vscode vue 自动格式化 安装Prettier和Vetur插件 选择设置,并且转到编辑文件。增加如下内容。 {"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","[vue]": {"editor.defaultFor…...
Webpack 5 混淆插件terser-webpack-plugin生命周期作用时机和使用注意事项
参考案例代码 海南酷森科技有限公司/webpack-simple-demo Terser(简要的/简短的) 混淆依据 混淆是发生在代码已经 bundle 之后的事情 变量或者函数在被引用或赋值时才能被混淆 孤立的函数或者变量可能会被移除,但不会被混淆,要…...
MQTT(Message Queuing Telemetry Transport)协议
文章目录 一、MQTT 的原理1. 通信模型2. 核心概念3. 工作流程 二、MQTT 的优势1. 轻量级2. 异步通信3. 可靠性4. 实时性5. 支持断线重连6. 跨平台支持7. 安全性 三、MQTT 的典型应用场景四、与其他协议的对比 MQTT(Message Queuing Telemetry Transport)…...
【MySQL学习笔记】MySQL存储过程
存储过程 1、基础语法2、变量2.1 系统变量2.2 用户自定义变量2.3 局部变量 3、if 流程控制4、参数5、case 流程控制6、循环结构6.1 while 循环6.2 repeat 循环6.3 loop 循环 7、游标 存储过程是事先经过编译并存储在数据库中的一段 SQL 语句的集合,调用存储过程可以…...
Vue2+OpenLayers实现折线绘制、起始点标记和轨迹打点的完整功能(提供Gitee源码)
目录 一、案例截图 二、安装OpenLayers库 三、代码实现 3.1、HTML页面 3.2、初始化变量 3.3、创建起始点位 3.4、遍历轨迹点 3.5、画折线 3.6、初始化弹窗信息 3.7、初始化地图上标点的点击事件 3.8、完整代码 四、Gitee源码 一、案例截图 二、安装OpenLayers库 n…...
基于Spring Boot的城市垃圾分类管理系统设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
linux: 文本编辑器vim
文本编辑器 vi的工作模式 (vim和vi一致) 进入vim的方法 方法一:输入 vim 文件名 此时左下角有 "文件名" 文件行数,字符数量 方法一: 输入 vim 新文件名 此时新建了一个文件并进入vim,左下角有 "文件名"[New File] 灰色的长方形就是光标,输入文字,左下…...
Eclipse Debug 调试
关于Eclipse的Debug调试功能,有几点重要的信息可以分享。 Debug的启动方式:Eclipse提供了多种启动程序调试的方式,包括通过菜单(Run –> Debug)、点击“绿色臭虫”图标、右键选择Debug As以及使用快捷键(F11)【0†source】。 调试中最常用…...
vue3+ts的<img :src=““ >写法
vue3ts的<img :src"" >写法<img :src"datasetImage" alt"数据分布示意图" /><script setup lang"ts">const datasetImage ref();datasetImage.value new URL(../../../assets/images/login-background.jpg, impo…...
探索R语言中的数据处理:序列统计
在数据分析中,我们经常需要处理复杂的顺序数据,例如测试的时间序列。在本篇博客中,我们将探讨如何使用R语言来处理一个特定的问题:统计四种测试(Test 1到Test 4)在不同顺序下的执行频率。 问题描述 假设我们有一个研究数据框,其中包含四种测试的日期,这些测试可以以任…...
Redis中有事务吗?有何不同?
在技术领域,我们常常被那些闪耀的、可见的成果所吸引。今天,这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力,让我们得以一窥未来的轮廓。然而,作为在企业一线构建、部署和维护复杂系统的实践者,我们深知…...
单片机与手机远距离通信技术方案全解析
1. 单片机与手机远距离通信的技术方案解析在物联网和智能硬件开发领域,单片机与手机的远程通信是一个基础但至关重要的技术需求。作为一名嵌入式开发工程师,我参与过多个需要远程通信的智能硬件项目,从智能家居设备到工业监测终端,…...
OpenClaw+百川2-13B-4bits:10分钟搭建学术资料收集机器人
OpenClaw百川2-13B-4bits:10分钟搭建学术资料收集机器人 1. 为什么需要学术资料收集机器人? 上周整理毕业论文参考文献时,我发现自己浪费了整整3个小时在重复操作上:在Google Scholar搜索关键词→逐一点开论文链接→手动判断相关…...
别再折腾Docker了!用CasaOS在Ubuntu上5分钟搞定个人轻NAS(附国内源配置)
别再折腾Docker了!用CasaOS在Ubuntu上5分钟搞定个人轻NAS(附国内源配置) 你是否曾经被Docker复杂的配置流程劝退?或者对传统NAS系统如TrueNAS的庞大资源占用感到头疼?如果你手头有一台闲置的旧电脑或树莓派,…...
ADC过采样技术提升嵌入式系统测量精度
1. ADC过采样技术概述在嵌入式系统开发中,ADC(模数转换器)的性能往往直接决定了整个系统的测量精度。标准的10位ADC在很多场合已经足够使用,但当我们需要更高精度的测量时,过采样技术就成为了一个经济有效的解决方案。…...
【数据结构】线索二叉树之中序遍历线索化详解与实现
在二叉树的遍历过程中,我们会发现大量的空指针域被浪费,而线索二叉树的核心思想就是利用这些空指针,将其指向节点的前驱或后继节点,从而实现二叉树的非递归遍历无需借助栈,提升遍历效率。本文将详细讲解中序遍历线索化…...
技术创业中的风险管理:从内核开发到商业稳定
技术创业中的风险管理:从内核开发到商业稳定 技术创业的风险挑战 作为一名从Linux内核开发者转型产品经理再到科技创业者的人,我深刻体会到风险管理在技术创业中的重要性。技术创业过程中充满了各种风险,从技术风险到商业风险,从市…...
卡尔曼滤波:详细齐全的代码实现与解析
卡尔曼滤波(代码非常详细、非常齐全) 1、卡尔曼滤波的含义是现时刻的最佳估计为在前一时刻的最佳估计的基础上根据现时刻的观测值作线性修正 2、卡尔曼滤波在数学上是一种线性最小方差统计估算方法,它是通过处理一系列带有误差的实际测量数据…...
InnoDB REDO LOG 详解:从原理到实现(基于 MySQL 8.0)
在现代关系型数据库系统中,事务的 持久性(Durability)是 ACID 特性的关键一环。为了在系统崩溃后仍能恢复数据一致性,InnoDB 引擎引入了 REDO LOG(重做日志)机制。 本文将深入剖析 REDO LOG 的作用、设计思…...
