ElasticSearch 地理位置查询与特殊查询

2年前 (2022) 程序员胖胖胖虎阿
263 0 0

松哥原创的 Spring Boot 视频教程已经杀青,感兴趣的小伙伴戳这里-->松哥要升级 SpringBoot 视频了,看看新增了哪些内容!


Es 系列更新到第 24 篇啦~今天我们来看 Es 中的地理位置查询与特殊查询!

地理位置查询:

特殊查询:

如果大家觉得视频风格还能接受,也可以看看松哥的付费视频:Spring Boot+Vue+微人事视频教程

以下是视频笔记:

注意,笔记只是视频内容的一个简要记录,因此笔记内容比较简单,完整的内容可以查看视频。

19.ElasticSearch 地理位置查询

19.1 数据准备

创建一个索引:

PUT geo
{
  "mappings": {
    "properties": {
      "name":{
        "type""keyword"
      },
      "location":{
        "type""geo_point"
      }
    }
  }
}

准备一个 geo.json 文件:

{"index":{"_index":"geo","_id":1}}
{"name":"西安","location":"34.288991865037524,108.9404296875"}
{"index":{"_index":"geo","_id":2}}
{"name":"北京","location":"39.926588421909436,116.43310546875"}
{"index":{"_index":"geo","_id":3}}
{"name":"上海","location":"31.240985378021307,121.53076171875"}
{"index":{"_index":"geo","_id":4}}
{"name":"天津","location":"39.13006024213511,117.20214843749999"}
{"index":{"_index":"geo","_id":5}}
{"name":"杭州","location":"30.259067203213018,120.21240234375001"}
{"index":{"_index":"geo","_id":6}}
{"name":"武汉","location":"30.581179257386985,114.3017578125"}
{"index":{"_index":"geo","_id":7}}
{"name":"合肥","location":"31.840232667909365,117.20214843749999"}
{"index":{"_index":"geo","_id":8}}
{"name":"重庆","location":"29.592565403314087,106.5673828125"}

最后,执行如下命令,批量导入 geo.json 数据:

curl -XPOST "http://localhost:9200/geo/_bulk?pretty" -H "content-type:application/json" --data-binary @geo.json

可能用到的工具网站:

http://geojson.io/#map=6/32.741/116.521

19.2 geo_distance query

给出一个中心点,查询距离该中心点指定范围内的文档:

GET geo/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": [
        {
          "geo_distance": {
            "distance""600km",
            "location": {
              "lat": 34.288991865037524,
              "lon": 108.9404296875
            }
          }
        }
      ]
    }
  }
}

以(34.288991865037524,108.9404296875) 为圆心,以 600KM 为半径,这个范围内的数据。

19.3 geo_bounding_box query

在某一个矩形内的点,通过两个点锁定一个矩形:

GET geo/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": [
        {
          "geo_bounding_box": {
            "location": {
              "top_left": {
                "lat": 32.0639555946604,
                "lon": 118.78967285156249
              },
              "bottom_right": {
                "lat": 29.98824461550903,
                "lon": 122.20642089843749
              }
            }
          }
        }
      ]
    }
  }
}

以南京经纬度作为矩形的左上角,以舟山经纬度作为矩形的右下角,构造出来的矩形中,包含上海和杭州两个城市。

19.4 geo_polygon query

在某一个多边形范围内的查询。

GET geo/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": [
        {
          "geo_polygon": {
            "location": {
              "points": [
                {
                  "lat": 31.793755581217674,
                  "lon": 113.8238525390625
                },
                {
                  "lat": 30.007273923504556,
                  "lon":114.224853515625
                },
                {
                  "lat": 30.007273923504556,
                  "lon":114.8345947265625
                }
              ]
            }
          }
        }
      ]
    }
  }
}

给定多个点,由多个点组成的多边形中的数据。

19.5 geo_shape query

geo_shape 用来查询图形,针对 geo_shape,两个图形之间的关系有:相交、包含、不相交。

新建索引:

PUT geo_shape
{
  "mappings": {
    "properties": {
      "name":{
        "type""keyword"
      },
      "location":{
        "type""geo_shape"
      }
    }
  }
}

然后添加一条线:

PUT geo_shape/_doc/1
{
  "name":"西安-郑州",
  "location":{
    "type":"linestring",
    "coordinates":[
      [108.9404296875,34.279914398549934],
      [113.66455078125,34.768691457552706]
      ]
  }
}

接下来查询某一个图形中是否包含该线:

GET geo_shape/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": [
        {
          "geo_shape": {
            "location": {
              "shape": {
                "type""envelope",
                "coordinates": [
                  [
            106.5234375,
            36.80928470205937
          ],
          [
            115.33447265625,
            32.24997445586331
          ]
                ]
              },
              "relation""within"
            }
          }
        }
      ]
    }
  }
}

relation 属性表示两个图形的关系:

  • within 包含
  • intersects 相交
  • disjoint 不相交

20.ElasticSearch 特殊查询

20.1 more_like_this query

more_like_this query 可以实现基于内容的推荐,给定一篇文章,可以查询出和该文章相似的内容。

GET books/_search
{
  "query": {
    "more_like_this": {
      "fields": [
        "info"
      ],
      "like""大学战略",
      "min_term_freq": 1,
      "max_query_terms": 12
    }
  }
}
  • fields:要匹配的字段,可以有多个
  • like:要匹配的文本
  • min_term_freq:词项的最低频率,默认是 2。
    特别注意,这个是指词项在要匹配的文本中的频率,而不是 es 文档中的频率
  • max_query_terms:query 中包含的最大词项数目
  • min_doc_freq:最小的文档频率,搜索的词,至少在多少个文档中出现,少于指定数目,该词会被忽略
  • max_doc_freq:最大文档频率
  • analyzer:分词器,默认使用字段的分词器
  • stop_words:停用词列表
  • minmum_should_match

20.2 script query

脚本查询,例如查询所有价格大于 200 的图书:

GET books/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "script": {
            "script": {
              "lang""painless",
              "source""if(doc['price'].size()!=0){doc['price'].value > 200}"
            }
          }
        }
      ]
    }
  }
}

20.3 percolate query

percolate query 译作渗透查询或者反向查询。

  • 正常操作:根据查询语句找到对应的文档 query->document
  • percolate query:根据文档,返回与之匹配的查询语句,document->query

应用场景:

  • 价格监控
  • 库存报警
  • 股票警告
  • ...

例如阈值告警,假设指定字段值大于阈值,报警提示。

percolate mapping 定义:

PUT log
{
  "mappings": {
    "properties": {
      "threshold":{
        "type""long"
      },
      "count":{
        "type""long"
      },
      "query":{
        "type":"percolator"
      }
    }
  }
}

percolator 类型相当于 keyword、long 以及 integer 等。

插入文档:

PUT log/_doc/1
{
  "threshold":10,
  "query":{
    "bool":{
      "must":{
        "range":{
          "count":{
            "gt":10
          }
        }
      }
    }
  }
}

最后查询:

GET log/_search
{
  "query": {
    "percolate": {
      "field""query",
      "documents": [
        {
          "count":3
        },
        {
          "count":6
        },
        {
          "count":90
        },
        {
          "count":12
        },
        {
          "count":15
        }
        ]
    }
  }
}

查询结果中会列出不满足条件的文档。

查询结果中的 _percolator_document_slot 字段表示文档的 position,从 0 开始计。

ElasticSearch 系列其他文章:

  1. 打算出一个 ElasticSearch 教程,谁赞成,谁反对?
  2. ElasticSearch 从安装开始
  3. ElasticSearch 第三弹,核心概念介绍
  4. ElasticSearch 中的中文分词器该怎么玩?
  5. ElasticSearch 索引基本操作
  6. ElasticSearch 文档的添加、获取以及更新
  7. ElasticSearch 文档的删除和批量操作
  8. ElasticSearch 文档路由,你的数据到底存在哪一个分片上?
  9. ElasticSearch 并发的处理方式:锁和版本控制
  10. ElasticSearch 中的倒排索引到底是什么?
  11. ElasticSearch 动态映射与静态映射
  12. ElasticSearch 四种字段类型详解
  13. ElasticSearch 中的地理类型和特殊类型
  14. ElasticSearch 23 种映射参数详解
  15. ElasticSearch 如何配置某个字段的权重?
  16. ElasticSearch 23 种映射参数详解【3】
  17. ElasticSearch 映射模版
  18. ElasticSearch 搜索入门
  19. ElasticSearch 全文搜索怎么玩?
  20. ElasticSearch 打错字还能搜索到?试试 fuzzy query!
  21. ElasticSearch 复合查询,理解 Es 中的文档评分策略!
  22. 想搜索附近评分较高的餐厅,ElasticSearch 大显身手!
  23. ElasticSearch 如何像 MySQL 一样做多表联合查询?






往期推荐
0
1

50+ 需求文档免费下载!

0
2

Spring Security 教程合集

0
3

接了两个私活,都是血汗钱

ElasticSearch 地理位置查询与特殊查询

本文分享自微信公众号 - 江南一点雨(a_javaboy)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

版权声明:程序员胖胖胖虎阿 发表于 2022年10月3日 上午2:56。
转载请注明:ElasticSearch 地理位置查询与特殊查询 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...