在我的上一篇文章 “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
 
					