通過以前的工做,目前已經完成了數據地圖的數據格式化和錄入記錄,目前咱們的數據地圖項目已經進行到最後階段,因此如今須要一個接口,進行格式化數據並輸出,其中須要用到Elasticsearch的全文檢索,檢索出數據後,使用php接口格式化數據輸出php
1、全文檢索html
例如,一個小時內,在中國範圍內,各個經緯度座標的,有操做行爲的,用戶個數node
由此需求,能夠獲得相應的Elasticsearch的搜索語句,以下:json
{
"size": 0,
"aggs": {
"filter_agg": {
"filter": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 90,
"lon": -34.453125
},
"bottom_right": {
"lat": -90,
"lon": 34.453125
}
}
}
},
"aggs": {
"2": {
"geohash_grid": {
"field": "location",
"precision": 2
},
"aggs": {
"3": {
"geo_centroid": {
"field": "location"
}
}
}
}
}
}
},
"stored_fields": [
"*"
],
"docvalue_fields": [
"@timestamp"
],
"query": {
"bool": {
"must": [
{
"range": {
"@timestamp": {
"gte": 1542692193461,
"lte": 1542695793461,
"format": "epoch_millis"
}
}
}
]
}
}
}
複製代碼
結果數據格式以下:api
{
"took": 428,
"timed_out": false,
"_shards": {
"total": 131,
"successful": 126,
"skipped": 121,
"failed": 5,
"failures": [
{
"shard": 0,
"index": "elastalert_status_status",
"node": "w10b9zEBRpuUEQsWvNqEig",
"reason": {
"type": "query_shard_exception",
"reason": "failed to find geo_point field [location]",
"index_uuid": "Dm4dpUtTTHitYN-TZFC-1g",
"index": "elastalert_status_status"
}
}
]
},
"hits": {
"total": 360942,
"max_score": 0,
"hits": []
},
"aggregations": {
"filter_agg": {
"2": {
"buckets": [
{
"3": {
"location": {
"lat": 48.58949514372008,
"lon": 7.584022147181843
},
"count": 252
},
"key": "u0",
"doc_count": 252
},
{
"3": {
"location": {
"lat": 54.420127907268785,
"lon": -3.120888938036495
},
"count": 181
},
"key": "gc",
"doc_count": 181
},
{
"3": {
"location": {
"lat": 42.32862451614172,
"lon": 3.7518564593602917
},
"count": 67
},
"key": "sp",
"doc_count": 67
},
{
"3": {
"location": {
"lat": 45.40799999143928,
"lon": 11.88589995726943
},
"count": 21
},
"key": "u2",
"doc_count": 21
},
{
"3": {
"location": {
"lat": 46.65579996071756,
"lon": 32.61779992841184
},
"count": 1
},
"key": "u8",
"doc_count": 1
}
]
},
"doc_count": 522
}
}
}
複製代碼
自此,咱們首先明白了,在Elasticsearch,如何書寫search語句查詢咱們想要的東西。 接下來,咱們須要書寫相應的php接口,來格式化輸出數據bash
2、接口書寫數據結構
代碼以下,有註釋:elasticsearch
<?php
/**
* Created by PhpStorm.
* User: ekisong
* Date: 2018/11/13
* Time: 15:55
*/
require 'vendor/autoload.php';
ini_set('display_errors','on');
error_reporting(E_ALL);
use Elasticsearch\ClientBuilder;
//建立Elasticsearch 的搜索對象client
$client = ClientBuilder::create()->setHosts(["localhost:9200"])->build();
//須要被篩選的字段名,默認值爲location
$fieldName = isset($_GET['field']) ? $_GET['field'] : 'location';
//地理圍欄左上角緯度,默認值90
$topLeftLat = isset($_GET['top_left_lat']) ? $_GET['top_left_lat'] : 90;
//地理圍欄左上角經度,默認值-180
$topLeftLon = isset($_GET['top_left_lon']) ? $_GET['top_left_lon'] : -180;
//地理圍欄右下角緯度,默認值-90
$bottomRightLat = isset($_GET['bottom_right_lat']) ? $_GET['bottom_right_lat'] : -90;
//地理圍欄右下角經度,默認值180
$bottomRightLon = isset($_GET['bottom_right_lon']) ? $_GET['bottom_right_lon'] : 180;
//時間範圍結束時間,默認當前時間
$endTime = isset($_GET['end_time']) ? $_GET['end_time'] : time()*1000;
//時間範圍其實時間,默認當前時間前15分鐘
$startTime = isset($_GET['start_time']) ? $_GET['start_time'] : $endTime - 15*60*1000;
//建立查詢結構體
$body = [
'size' => 0,
'query' => [
'bool' => [
'must' => [
[
'range' => [
'@timestamp' => [
'gte' => $startTime,
'lte' => $endTime,
'format' => 'epoch_millis'
]
]
]
]
]
],
'aggs' => [
'filter_agg' => [
'filter' => [
'geo_bounding_box' => [
'location' => [
'top_left' => [
'lat' => $topLeftLat,
'lon' => $topLeftLon
],
'bottom_right' => [
'lat' => $bottomRightLat,
'lon' => $bottomRightLon
]
]
]
],
'aggs' => [
'2' => [
'geohash_grid' => [
'field' => $fieldName,
'precision' => 1
],
'aggs' => [
'3' => [
'geo_centroid' => [
'field' => $fieldName
]
]
]
]
]
]
],
'stored_fields' => [
'*'
],
'docvalue_fields' => [
'@timestamp'
]
];
//搜索參數
$params = [
'index' => 'logstash-*',
'body' => $body
];
//Elasticsearch搜索結果原始數據
$response = $client->search($params);
$resultTmp = $response['aggregations']['filter_agg']['2']['buckets'];
$data = array();
//格式化數據
foreach ($resultTmp as $doc)
{
$lat = $doc['3'][$fieldName]['lat'];
$lon = $doc['3'][$fieldName]['lon'];
$count = $doc['doc_count'];
$tmp = [
'count' => $count,
'geometry' => [
'type' => 'Point',
'coordinates' => [$lon,$lat]
]
];
$data[] = $tmp;
}
$result = array('data'=>$data,'error_msg'=>'','flag'=>1);
if (empty($data))
{
$result['error_msg'] = 'no data';
$result['flag'] = 0;
}
//最終輸出
echo json_encode($result);
exit();
複製代碼
因爲H5頁面插件限制,因此須要特定的數據格式。因此最終輸出結果以下:ide
[{
"count": 6,
"geometry": {
"type": "Point",
"coordinates": ["116.395645", "39.929986"]
}
}, {
"count": 6,
"geometry": {
"type": "Point",
"coordinates": ["121.487899", "31.249162"]
}
}, {
"count": 5,
"geometry": {
"type": "Point",
"coordinates": ["117.210813", "39.14393"]
}
}, {
"count": 4,
"geometry": {
"type": "Point",
"coordinates": ["106.530635", "29.544606"]
}
}]
複製代碼
至此,咱們數據地圖項目在數據方面的工做暫且告一段落。ui
參考文檔:
www.elastic.co/guide/en/elasticsearch/reference/current/search.html