在我的上一篇文章 “Elasticsearch:使用 Node.js 将实时数据提取到 Elasticsearch 中(一)”,我详细描述了如何如何使用 Node.js 来采集地震数据。在今天的文章中,我们来详细描述如何对数据可视化。我们还将创建一个 web 应用来对我们的地震数据进行搜索。
在进行可视化之前,我们可以让我们的应用运用一段时间以收集一定的数据。
创建可视化
在进行可视化之前,我们需要为数据创建一个 data view。我们按照如下的步骤来进行:
我们可以在 Discover 中进行查看:
我们可以查看地震数据的详细数据。
我们首先为这个数据制作一个表格:
按照同样的方法我们添加其它的字段:
我们把当前的视图保存下来:
我们接下来创建一个 Dashboard:
这样我们得到了第一个可视化图。我们可以看到 table 中的 url 字段是不可以点击的。如果我们需要针对它进行点击,我们需要设置它为 keyword 字段,并在 data view 中对它进行配置。
我们接下来创建一个按照时间循序发生地震的时序图:
我们接下来找到最大的 Magnitude 的值:
按照同样的方法,我们找到最小的 Mangnitude 值:
我们接下来描绘 Max mangnitude 随着时间变化的曲线。我们添加一个 Lens 的可视化:
按照同样的方法,我们添加一个 Min mag 的曲线图:
最后,我们使用 Maps 来显示地震所在的位置:
从上面我们可以清楚地看到地震发生的位置。点击上面的 Save & return:
这样我们就得到了地震的分布图。
我们点击右上角的 Save 按钮就可以保存这个 dashboard 了。
好了,我们的可视化就做到这里。
创建 web 应用来查询地震
接下来我们来创建一个 web 应用来对地震的数据进行查询。我们接着之前在文章 “Elasticsearch:使用 Node.js 将实时数据提取到 Elasticsearch 中(一)” 中的代码。我们将创建一个 React 的客户端来使得终端用户来查询 Elasticsearch。最终的界面如下:
我们的客户端允许用户根据地震类型、震级、位置和日期范围搜索地震。 它还允许用户按数量级的升序或降序对搜索结果进行排序。
当用户点击搜索按钮时,用户输入通过 HTTP 请求发送到服务器。服务器将用户输入传递到 Elasticsearch 请求中,并将请求发送到 Elasticsearch。
Elasticsearch 检索相关文档并将文档发送到服务器。 服务器将文档发送给客户端。
客户端收到文件后,以卡片的形式显示结果。 每张卡片包含一次地震的信息。
创建客户端
我们在另外一个 terminal 中,在 earthquake_app 的目录中,执行如下的命令:
npx create-react-app client
运行完上面的命令后,我们会发现有一个新的目录 client 被生成:
-
$ ls
-
client node_modules
package.json
-
config
package-lock.json server
我们接下来安装 Axios。我们进入 client 目录中:
-
$ cd client/
-
$ ls
-
node_modules package.json yarn.lock
我们将使用一个名为 axios 的库向我们的服务器发送 HTTP 请求。通过执行以下命令安装 axios。
npm i axios
-
$ npm i axios
-
npm notice Beginning October
4,
2021, all connections to the npm registry - including
for
package
installation - must
use TLS
1.2 or higher. You are currently using plaintext http to connect. Please visit the GitHub blog
for
more
information: https:
//github.blog/2021-08-23-npm-registry-deprecating-tls-1-0-tls-1-1/
-
npm notice Beginning October
4,
2021, all connections to the npm registry - including
for
package
installation - must
use TLS
1.2 or higher. You are currently using plaintext http to connect. Please visit the GitHub blog
for
more
information: https:
//github.blog/2021-08-23-npm-registry-deprecating-tls-1-0-tls-1-1/
-
-
added
5 packages, removed
1 package, and changed
9 packages
in
6s
-
-
209 packages are looking
for
funding
-
run `npm fund`
for
details
运行完上面的命令后,我们可以查当前目录下 package.json 的内容:
-
$
pwd
-
/Users/liuxg/demos/earthquake_app/client
-
$
cat package.json
-
{
-
"name":
"client",
-
"version":
"0.1.0",
-
"private":
true,
-
"dependencies": {
-
"axios":
"^1.2.2",
-
"react":
"^18.2.0",
-
"react-dom":
"^18.2.0",
-
"react-scripts":
"5.0.1"
-
}
-
}
我们可以看到 react 及 axios 已经被成功地添加到 dependencies 里去了。
在 package.json 文件中,我们将添加 "proxy" 键并将代理指向运行 Node.js 服务器的 localhost:5001。这样我们的 package.json 的内容如下:
-
{
-
"name":
"client",
-
"version":
"0.1.0",
-
"private": true,
-
"dependencies": {
-
"@testing-library/jest-dom":
"5.16.5",
-
"@testing-library/react":
"13.3.0",
-
"@testing-library/user-event":
"13.5.0",
-
"axios":
"^1.2.2",
-
"react":
"^18.2.0",
-
"react-dom":
"^18.2.0",
-
"react-scripts":
"5.0.1",
-
"web-vitals":
"^3.1.0"
-
},
-
"scripts": {
-
"start":
"react-scripts start",
-
"build":
"react-scripts build",
-
"test":
"react-scripts test",
-
"eject":
"react-scripts eject"
-
},
-
"proxy":
"http://localhost:5001",
-
"eslintConfig": {
-
"extends": [
-
"react-app",
-
"react-app/jest"
-
]
-
},
-
"browserslist": {
-
"production": [
-
">0.2%",
-
"
not dead
",
-
"
not op_mini all
"
-
],
-
"development
": [
-
"
last
1 chrome version
",
-
"
last
1 firefox version
",
-
"
last
1 safari version
"
-
]
-
}
-
}
我们可以按照如下的方法来统一安装所需要的 Node.js 库:
-
$ pwd
-
/Users/liuxg/demos/earthquake_app/client
-
$ npm install
-
npm notice Beginning October
4,
2021, all connections to the npm registry - including
for
package
installation - must
use TLS
1.2 or higher. You are currently using plaintext http to connect. Please visit the GitHub blog
for
more
information: https:
//github.blog/2021-08-23-npm-registry-deprecating-tls-1-0-tls-1-1/
-
npm notice Beginning October
4,
2021, all connections to the npm registry - including
for
package
installation - must
use TLS
1.2 or higher. You are currently using plaintext http to connect. Please visit the GitHub blog
for
more
information: https:
//github.blog/2021-08-23-npm-registry-deprecating-tls-1-0-tls-1-1/
-
-
up to date
in
1s
-
-
222 packages are looking
for
funding
-
run `npm fund`
for
details
为了方便大家学习,我把最终的代码放到 github 上:GitHub - liu-xiao-guo/earthquake-app-final。
为了能够让我们的 web 应用访问 Elasticsearch,我们针对 server.js 进行修改:
server/server.js
-
const express =
require(
'express');
-
const client =
require(
'./elasticsearch/client');
-
const cors =
require(
'cors');
-
const {
Client } =
require(
'@elastic/elasticsearch');
-
-
const app =
express();
-
-
const port =
5001;
-
-
//Define Routes
-
const data =
require(
'./routes/api/data')
-
app.
use(
'/api/data', data);
-
-
app.
get(
'/',
(req, res) => {
-
res.
send(
'Hello World!')
-
})
-
-
app.
use(
cors());
-
-
app.
get(
'/results',
(req, res) => {
-
const passedType = req.
query.
type;
-
const passedMag = req.
query.
mag;
-
const passedLocation = req.
query.
location;
-
const passedDateRange = req.
query.
dateRange;
-
const passedSortOption = req.
query.
sortOption;
-
-
console.
log(
"passedType = " + passedType);
-
console.
log(
"passedMag = " + passedMag);
-
console.
log(
"passedLocation = " + passedLocation);
-
console.
log(
"passedDateRange = " + passedDateRange);
-
console.
log(
"passedSortOption = " + passedSortOption);
-
-
var request = {
-
sort: [
-
{
-
mag: {
-
order: passedSortOption,
-
},
-
},
-
],
-
size:
300,
-
query: {
-
bool: {
-
filter: [
-
{
-
term: {
type: passedType },
-
},
-
{
-
range: {
-
mag: {
-
gte: passedMag,
-
},
-
},
-
},
-
{
-
match: {
place: passedLocation },
-
},
-
// for those who use prettier, make sure there is no whitespace.
-
{
-
range: {
-
'@timestamp': {
-
gte:
`now-${passedDateRange}d`,
-
lt:
'now',
-
},
-
},
-
},
-
],
-
},
-
},
-
}
-
-
console.
log(
"request = " +
JSON.
stringify(request));
-
-
async
function
sendESRequest(
) {
-
const body =
await client.
search({
-
index:
'earthquakes',
-
body: request,
-
});
-
-
console.
log(body);
-
res.
json(body.
hits.
hits);
-
}
-
-
console.
log(
"Send ES Request ....")
-
sendESRequest();
-
});
-
-
app.
listen(port,
() =>
console.
log(
`Server listening at http://localhost:${port}`));
如上所示,我们增加了一个接口 /results。它可以通过如下的形式来对它进行访问:
curl -XGET http://localhost:5001/api/data/earthquakes?type=xxx&mag=xxx&location=xxx&dateRange=xxx&sortOption=xxx
上面的 xxx 是可以通过 web 的界面来获得的:
在上面,它定义了一个搜索的请求。它相当于 Elasticsearch 这样的一个查询:
-
GET earthquakes/_search
-
{
-
"size": 300,
-
"sort": [
-
{
-
"mag": {
-
"order":
"desc"
-
}
-
}
-
],
-
"query": {
-
"bool": {
-
"filter": [
-
{
-
"term": {
-
"type":
"earthquake"
-
}
-
},
-
{
-
"range": {
-
"mag": {
-
"gte":
"1.5"
-
}
-
}
-
},
-
{
-
"match": {
-
"place":
"Alaska"
-
}
-
},
-
{
-
"range": {
-
"@timestamp": {
-
"gte":
"now-7d",
-
"lt":
"now"
-
}
-
}
-
}
-
]
-
}
-
}
-
}
我们把返回的结果通过一个个 card 来进行展示:
我们需要在 client 的目录下使用如下的命令来启动 web 应用:
npm start
我们可以改变上面的搜索参数来搜索 Elasticsearch 数据,比如:
好了,今天的展示就到这里。希望大家也一起学到了知识!
转载:https://blog.csdn.net/UbuntuTouch/article/details/128517222