Elastic Search

ES 命令

delete index

curl -X DELETE ‘http://localhost:9200/samples'

list all indexes

curl -X GET ‘http://localhost:9200/_cat/indices?v'

list all docs in index

curl -X GET ‘http://localhost:9200/sample/_search'

query using URL parameters

curl -X GET http://localhost:9200/samples/_search?q=school:Harvard

curl -XGET –header ‘Content-Type: application/json’ http://localhost:9200/samples/_search -d ‘{
“query” : {
“match” : { “school”: “Harvard” }
}
}’

list index mapping

curl -X GET http://localhost:9200/samples

http://10.16.73.100:12801/_mapping/

Add Data

curl -XPUT –header ‘Content-Type: application/json’ http://localhost:9200/samples/_doc/1 -d ‘{
“school” : “Harvard”
}’

Update Doc

curl -XPUT –header ‘Content-Type: application/json’ http://localhost:9200/samples/_doc/2 -d ‘
{
“school”: “Clemson”
}’

curl -XPOST –header ‘Content-Type: application/json’ http://localhost:9200/samples/_doc/2/_update -d ‘{
“doc” : {
“students”: 50000}
}’

backup index

curl -XPOST –header ‘Content-Type: application/json’ http://localhost:9200/_reindex -d ‘{
“source”: {
“index”: “samples”
},
“dest”: {
“index”: “samples_backup”
}
}’

ES DSL查询

query DSL ES中索引的数据都会存储一个_score分值,分值越高就代表越匹配

filter DSL 是或者不是,它不会去计算任何分值,也不会关心返回的排序问题,因此效率会高一点。

查询DSL(query DSL)和过滤DSL(filter DSL

基本查询demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"query": {
"bool": {
"must": [{
"term": {
"jz_post-operate_label": "rpo"
}
}, {
"range": {
"jz_post-id": {
"lt": 5193035
}
}
}]
}
},
"sort": [{
"jz_post-id": {
"order": "desc"
}
}]

,
"_source": [
"jz_post-id"
]
}

geo 距离查询

ES 版本实现

需要将经纬度设置字符串或者数据,对象类型。数据类型设置为geo_point才能查询,底层是Geohash 实现

位置过滤:

  1. geo_distance 查找距离某个中心点距离在一定范围内的位置
  2. geo_bounding_box 查找某个长方形区域内的位置
  3. geo_distance_range 查找距离某个中心的距离在min和max之间的位置
  4. geo_polygon 查找位于多边形内的地点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{
"query": {
"bool": {
"must_not": [
{
"terms": {
"jz_post-id": [
5433682
]
}
}
],
"filter": [
{
"term": {
"jz_post-source": 91
}
},
{
"term": {
"jz_post-listing_status": 5
}
},
{
"nested": {
"path": "jz_post_address",
"query": {
"constant_score": {
"filter": {
"geo_distance": {
"distance": "2km",
"jz_post_address.location": {
"lat": "30.26977011",
"lon": "120.15865222"
}
}
},
"boost": 1
}
}
}
}
]
}
},
"sort": [
{
"_geo_distance": {
"jz_post_address.location": {
"lat": "30.26977011",
"lon": "120.15865222"
},
"unit": "km",
"order": "asc"
}
}
]
}

php+mysql实现

  1. 计算范围,可以做搜索用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function GetRange($lat,$lon,$raidus){
//计算纬度
$degree = (24901 * 1609) / 360.0;
$dpmLat = 1 / $degree;
$radiusLat = $dpmLat * $raidus;
$minLat = $lat - $radiusLat; //得到最小纬度
$maxLat = $lat + $radiusLat; //得到最大纬度
//计算经度
$mpdLng = $degree * cos($lat * (PI / 180));
$dpmLng = 1 / $mpdLng;
$radiusLng = $dpmLng * $raidus;
$minLng = $lon - $radiusLng; //得到最小经度
$maxLng = $lon + $radiusLng; //得到最大经度
//范围
$range = array(
'minLat' => $minLat,
'maxLat' => $maxLat,
'minLon' => $minLng,
'maxLon' => $maxLng
);
return $range;
}
  1. 获取范围内的所有数据
1
2
3
4
5
6
7
8
$result = GetRange(110.325945,20.031541,5000);

$where = " (`jingdu` between ".$result['minLat']." and ".$result['maxLat'].") and ( `weidu` between ".$result['minLon']." and ".$result['maxLon']." ) ";
$query = $db->query("select * from distance_table where $where order BY id DESC ");
while ( $row = $db->fetch_array($query) ) {
$list[] = $row['all_name'];
}
print_r($list);

PHP计算经纬度坐标之间的距离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getDistance($lat1, $lng1, $lat2, $lng2, $len_type = 1, $decimal = 2) {
$radLat1 = $lat1 * PI / 180.0;
$radLat2 = $lat2 * PI / 180.0;
$a = $radLat1 - $radLat2;
$b = ($lng1 * PI / 180.0) - ($lng2 * PI / 180.0);
$s = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
$s = $s * EARTH_RADIUS;
$s = round($s * 1000);
if ($len_type > 1)
{
$s /= 1000;
}
return round($s, $decimal);
}

精确匹配查询(match_phrase)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"jz_post-city_id": 289
}
},
{
"term": {
"jz_post-job_date_type": 0
}
},
{
"term": {
"jz_post-company_id": 1836671
}
},
{
"terms": {
"jz_post-listing_status": [
0,
5
]
}
}
],
"should": [
{
"match_phrase": {
"jz_post-title": "诚心招聘业务员"
}
}
]
}
}
}
}
}

短语前缀匹配

它与短语匹配的区别为它能匹配的方位更广,它可以命中到短语+其他内容的内容

1
2
3
4
5
6
7
{
"query": {
"match_phrase_prefix": {
"FIELD": "PREFIX"
}
}
}

ES文档参考

分享即是成长