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…...
Qwen3-Coder-30B-A3B-Instruct-FP8:终极代码模型对比分析指南
Qwen3-Coder-30B-A3B-Instruct-FP8:终极代码模型对比分析指南 【免费下载链接】Qwen3-Coder-30B-A3B-Instruct-FP8 项目地址: https://ai.gitcode.com/hf_mirrors/Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8 在当今AI代码生成领域,Qwen3-Coder-30B-…...
告别网盘客户端!用Alist+RaiDrive把百度云盘变成电脑本地文件夹(保姆级图文教程)
用AlistRaiDrive实现网盘本地化管理的终极方案 你是否厌倦了电脑上安装多个网盘客户端,不仅占用系统资源,操作还繁琐割裂?每次上传下载文件都要在不同客户端间切换,效率低下。现在,通过Alist和RaiDrive的组合…...
基于Arduino的模块化DIY智能时钟:从RTC到RGB LED的完整实现
1. 项目概述:打造一台高度可定制的DIY RGB LED时钟如果你和我一样,对市面上千篇一律的电子钟感到审美疲劳,同时又对Arduino和电子DIY充满热情,那么这个项目可能就是为你准备的。我们不是在简单地组装一个套件,而是在亲…...
全链路压测实战:双十一级别的流量,我是这样扛住的
作为一名在质量保障领域摸爬滚打多年的测试工程师,我深知传统的单接口压测在如今分布式架构下的无力感。当业务流量达到双十一这种脉冲式、高并发的级别时,任何一个非核心链路上的“短板”都可能引发系统性的雪崩。全链路压测不再是选择题,而…...
终极免费方案:WandEnhancer完整解锁WeMod Pro功能快速指南
终极免费方案:WandEnhancer完整解锁WeMod Pro功能快速指南 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 你是否渴望享受WeMod Pro会员的所…...
MeloTTS实战:多语言语音合成的高效解决方案
MeloTTS实战:多语言语音合成的高效解决方案 【免费下载链接】MeloTTS High-quality multi-lingual text-to-speech library by MyShell.ai. Support English, Spanish, French, Chinese, Japanese and Korean. 项目地址: https://gitcode.com/GitHub_Trending/me/…...
styled-theming 性能优化:如何避免主题切换时的性能瓶颈
styled-theming 性能优化:如何避免主题切换时的性能瓶颈 【免费下载链接】styled-theming Create themes for your app using styled-components 项目地址: https://gitcode.com/gh_mirrors/st/styled-theming styled-theming 是一个专为 styled-components …...
二十六.签名与脚本(1)--脚本介绍
1.区块链脚本介绍在之前的章节中,我们了解了签名与验证相关,但是btc的交易数据,签名和验证,不是单纯的,还有脚本深度参与其中。我们从开始来:bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletT…...
告别枯燥理论!用Unity脚本生命周期与预制体玩转一个“会变身的敌人”
用Unity打造会变身的敌人:脚本生命周期与预制体的实战应用在游戏开发中,敌人AI的行为设计往往是新手开发者最感兴趣也最容易感到困惑的部分。Unity的脚本生命周期和预制体系统为这类需求提供了强大支持,但教科书式的讲解常常让学习者陷入枯燥…...
Keil µVision反汇编窗口内容导出方案与调试技巧
1. 问题背景与需求解析在嵌入式开发过程中,调试环节往往占据大量时间。Keil Vision作为业界广泛使用的集成开发环境(IDE),其调试器功能强大但某些细节功能仍有提升空间。最近我在使用C251架构开发汽车电子控制单元时,就遇到了一个看似简单却影…...
