zoukankan      html  css  js  c++  java
  • elasticsearch 学习

    es是什么?

    es是基于Apache Lucene的开源分布式(全文)搜索引擎,,提供简单的RESTful API来隐藏Lucene的复杂性。

    1.分布式的实时存储,每个字段都被索引可被搜索

    2.分布式实时分析搜索引擎

    3.可以扩展到成千台服务器,处理pb级结构化或非结构化数据

    es下载和安装

    java for windows

    es对于java jdk的版本有需求,必须是java1.8及以上版本。

    安装步骤参考:https://www.cnblogs.com/Neeo/articles/10368280.html

    es for windows

    es开箱即用,也就是解压即可使用,安装参考https://www.cnblogs.com/Neeo/articles/10371306.html

    kibana for windows

    Kibana是一个为ElasticSearch 提供的数据分析的 Web 接口。可使用它对日志进行高效的搜索、可视化、分析等各种操作。

    安装参考:https://www.cnblogs.com/Neeo/articles/10371213.html

    es的快速上手

    关系型数剧库     es

    数据库              索引indices

    表                     type 类型

    记录                 documents 文档

    字段                 字段fields

    elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)。

    文档
    
    文档的特性:自我包含,层次型、结构灵活、无模式
    类型:在es6.x版本开始,一个索引下面只能有一个类型,类型是是文档的容器,并且,类型记录了字段和值的映射关系。
    索引,索引是映射类型的容器,elasticsearch中的索引是一个非常大的文档集合。索引存储了映射类型的字段和其他设置。然后它们被存储到了各个分片上了。
    物理:节点,分片
    
    节点,一个集群至少有一个节点,节点内可以有多个索引。在创建索引时,默认创建5个主分片,每个主分片搭配一个复制分片。
    分片:文档存储在各个分片上,一个分片也是一个Lucene索引。
    倒排索引,倒排索引是一个包含不重复词条的文档,我们称该文档为倒排文档。详情参考
    es的索引和Lucene的索引对比
    es的索引是由多个分片组成,而每个分片则是一个Lucene索引。
    一个Lucene索引能存储不超过21亿篇文档,或者不超过2740亿个唯一词条。

    基本操作

    PUT s18/doc/1
    {
      "name":"zhangsan",
      "age":18,
      "tags":"",
      "b":"19970505"
    }
    #结果中的result则是操作类型,现在是created,表示第一次创建。如果我们再次点击执行该命令,那么result则会是updated。我们细心则会发现_version开始是1,现在你每点击一次就会增加一次。表示第几次更改。
    
    PUT s18/doc/2
    {
      "name":"lisi",
      "age":15,
      "tangs":"",
      "b":"11232102"
    }
    
    PUT s18/doc/3
    {
      "name":"wangwu",
      "age":18,
      "tangs":"",
      "b":"20150420"
    }
    #上例中,我们添加3篇文档,首先检查索引s18是否存在,不存在先创建,存在则添加(或更新)文档。
    
    #查看指定文档
    GET s18/doc/1
    #查询所有
    GET s18/doc/_search
    #按条件查询
    GET s18/doc/_search?q=name:zhangsan
    #查看索引详情
    GET s18
    
    DELETE s18/doc/1 #删除指定文档
    DELETE s18 #删除索引
    
    #这样修改 其他字段就没有了
    PUT s18/doc/1
    {
      "tags":"帅气"
    }
    
    
    #修改指定字段
    POST s18/doc/1/_update
    {
      "doc": {
        "tags":"很浪"
      }
    }
    
    GET s18/doc/1

    dsl 基本操作

    #查出年纪等于18的
    GET s18/doc/_search
    {
      "query": {
        "match": {
          "age": 18
        }
      }
    }
    
    #查询多个条件
    GET s18/doc/_search
    {
      "query":{
        "match": {
          "tangs": "浪 骚"
        }
      }
    }
    
    #2中查询所有
    GET s18/doc/_search
    
    GET s18/doc/_search
    {
      "query": {
        "match_all": {}
      }
    }

    排序

    • 降序:desc
    • 升序:asc
    #排序 sort 倒序asc
    GET s18/doc/_search
    {
      "query":{
        "match_all": {}
      },
      "sort":[
        {
          "age":{
            "order":"desc"
          }
        }
        ]
    }
    ###正序
    GET s18/doc/_search
    {
      "query":{
        "match_all": {}
      },
      "sort": [
        {
          "age": {
            "order": "asc"
          }
        }
      ]
    }
    ######注意 不是所有的字段都能排序,最好只能是数字

    分页

    • from:从哪开始查
    • size:返回几条结果
    GET s18/doc/_search
    {
      "query":{
        "match_all": {}
      },
      "from": 0,
      "size":2
    }
    
    GET s18/doc/_search
    {
      "query": {
        "match_all": {}
      },
      "from": 2,
      "size": 20
    }

    bool查询

    • must:与关系,相当于关系型数据库中的and
    • should:或关系,相当于关系型数据库中的or
    • must_not:非关系,相当于关系型数据库中的not
    • filter:过滤条件。
    • range:条件筛选范围。
    • gt:大于,相当于关系型数据库中的>
    • gte:大于等于,相当于关系型数据库中的>=
    • lt:小于,相当于关系型数据库中的<
    • lte:小于等于,相当于关系型数据库中的<=
    #布尔查询bool should(or) must(and) must_not(not)
    #查找帅的 或年纪等于17  should
    GET s18/doc/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "tangs": ""
              }
            },
            {
              "match": {
                "age": "17"
              }
            }
          ]
        }
      }
    }
    
    #查询 年纪18的 帅的  must
    GET s18/doc/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "age": "18"
              }
            },
            {
              "match": {
                "tangs": ""
              }
            }
          ]
        }
      }
    }
    #查询 不是18的也不是17的 must_not
    GET s18/doc/_search
    {
      "query": {
        "bool": {
          "must_not": [
            {
              "match": {
              "age": "18"
            }
            },
            {
              "match": {
                "age": "17"
              }
            }
          ]
        }
      }
    }
    
    
    #lt小于 lte小于等于 gt大于 get大于等于
    #查询小于20的女的
    GET s18/doc/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "sex": ""
              }
            }
          ],
          "filter": {
            "range": {
              "age": {
                "lt": 20
              }
            }
          }
        }
      }
    }
    #查询年纪小于等于18的非女性
    GET s18/doc/_search
    {
      "query": {
        "bool": {
          "must_not": [
            {
              "match": {
                "sex": ""
              }
            }
          ],
          "filter": {
            "range": {
              "age": {
                "lte": 18
              }
            }
          }
        }
      }
    }

    高亮查询

    #highlight 属性来实现结果高亮显示
    #pre_tags 用来实现我们的自定义标签的前半部分
    #post_tags 实现标签的后半部分
    需要的字段名称添加到fields内即可

    PUT zhifou/doc/4
    {
      "name":"石头",
      "age":29,
      "from":"gu",
      "desc":"粗中有细,狐假虎威",
      "tags":["", "",""]
    }
    
    GET zhifou/doc/_search
    {
      "query": {
        "match": {
          "from": "gu"
        }
      },
      "highlight": {
        "pre_tags": "<b class='key' style='color:red'>",
        "post_tags": "</b>",
        "fields": {
          "from": {}
        }
      }
    }
    PUT s18/doc/6
    {
      "name":"wangdi",
      "desc": "骚的打漂"
    }
    
    GET s18/doc/_search
    {
      "query": {
        "match": {
          "desc": "打漂"
        }
      },
      "highlight": {
        "pre_tags": "<b style='color:red;font-size:20px;' class='wangdi'>", 
        "post_tags": "</b>", 
        "fields": {
          "desc": {}
        }
      }
    }

    结果过滤

    GET s18/doc/_search
    {
      "query": {
        "match": {
          "name": "zhangsan"
        }
      }
      , "_source": ["name","age"]
    }

    聚合查询  avg、max、min、sum

    #聚合查询
    GET s18/doc/_search
    {
      "query": {
        "match": {
          "sex": ""
        }
      },
      "aggs": {
        "my_sum": {
          "sum": {
            "field": "age"
          }
        }
      }
    }
    #查询年纪最大的男生max
    GET s18/doc/_search
    {
      "query": {
        "match": {
          "sex": ""
        }
      },
      "aggs": {
        "my_max": {
          "max": {
            "field": "age"
          }
        }
      }
    }
    
    #查询年纪最小的min
    GET s18/doc/_search
    {
      "aggs": {
        "my_min": {
          "min": {
            "field": "age"
          }
        }
      }
    }
    
    #求平局 avg
    GET s18/doc/_search
    {
      "aggs": {
        "my_avg": {
          "avg": {
            "field": "age"
          }
        }
      }
    }

    field是以age为分组

    分组

    #分组 根据年龄 10-20 20-30 30-100
    GET s18/doc/_search
    {
      "query": {
        "match": {
          "sex": ""
        }
      },
      "aggs": {
        "my_group": {
          "range": {
            "field": "age",
            "ranges": [
              {
                "from": 1,
                "to": 15
              },
              {
                "from": 15,
                "to": 20
              },
              {
                "from": 30,
                "to":100
              }
            ]
          }
        }
      }
    }
    #分组 根据年龄 10-20 20-30 30-100 对每组年龄求和
    GET s18/doc/_search
    {
      "query": {
        "match": {
          "sex": ""
        }
      },
      "aggs": {
        "group": {
          "range": {
            "field": "age",
            "ranges": [
              {
                "from": 10,
                "to": 15
              },
              {
                "from": 16,
                "to":20
              }
            ]
          },
          "aggs": {
            "my_sum": {
              "sum": {
                "field": "age"
              }
            }
          }
        }
      }
    }

    mappings 映射  相当于原来由elasticsearch自动帮我们定义表结构

    PUT s2/doc/1
    {
      "name":"zhangsan",
      "age":21,
      "desc":"低调"
    }
    
    PUT s2/doc/2
    {
      "name":"lisi",
      "age":20,
      "desc":"骚气"
    }
    
    GET s2/doc/_search
    {
      "query": {
        "match": {
          "desc": "骚气"
        }
      }
    }

    mapping的dynamic的三种状态

    • 动态映射(dynamic:true)
    • 静态映射(dynamic:false)
    • 严格模式(dynamic:strict)
    PUT m1
    {
      "mappings": {
        "doc":{
          "properties":{
            "name":{
              "type":"text"
            },
            "age":{
              "type":"long"
            }
          }
        }
      }
    }
    
    GET m1/_mapping
    
    GET m1/doc/_search
    {
      "query": {
        "match": {
          "sex": "不详"
        }
      }
    }

    静态模式

    PUT s5
    {
      "mappings": {
        "doc":{
          "dynamic": false,
          "properties":{
            "name":{
              "type":"text"
            }
          }
        }
      }
    }
    
    PUT s5/doc/1
    {
      "name":"玉冰"
    }
    
    PUT s5/doc/2
    {
      "name":"peiqin",
      "age": 17
    }
    
    GET s5/_mapping
    GET s5/doc/_search

    #可以看到elasticsearch并没有为新增的sex建立映射关系。所以查询不到。
    当elasticsearch察觉到有新增字段时,因为dynamic:false的关系,会忽略该字段,但是仍会存储该字段。
    在有些情况下,dynamic:false依然不够,所以还需要更严谨的策略来进一步做限制。

    严格模式

    PUT m4
    {
      "mappings": {
        "doc": {
          "dynamic": "strict", 
          "properties": {
            "name": {
              "type": "text"
            },
            "age": {
              "type": "long"
            }
          }
        }
      }
    }
    
    PUT m4/doc/1
    {
      "name": "小黑",
      "age": 18
    }
    PUT m4/doc/2
    {
      "name": "小白",
      "age": 18,
      "sex": "不详"
    }

    mapping的ignore_above

    PUT s7
    {
      "mappings": {
        "doc":{
          "properties":{
            "title":{
              "type":"keyword",
              "ignore_above": 10
            }
          }
        }
      }
    }
    
    PUT s7/doc/1
    {
      "title": "从手机、平板电脑、路由器和视频游戏控制台"
    }
    
    PUT s7/doc/2
    {
      "title": "1234567"
    }
    
    
    GET s7/doc/_search
    {
      "query": {
        "match": {
          "title": "1234567"
        }
      }
    }

    index 

     index属性默认为true,如果该属性设置为false,那么,elasticsearch不会为该属性创建索引,也就是说无法当做主查询条件。

    PUT s8
    {
      "mappings": {
        "doc":{
          "properties":{
            "t1":{
              "type":"text",
              "index": true
            },
            "t2":{
              "type":"text",
              "index": false
            }
          }
        }
      }
    }
    
    
    PUT s8/doc/1
    {
      "t1":"论母猪的产前保养",
      "t2":"论母猪的产后护理"
    }
    
    GET s8/doc/_search
    {
      "query": {
        "match": {
          "t1": "母猪"
        }
      }
    }
    
    GET s8/doc/_search
    {
      "query": {
        "match": {
          "t2": "母猪"
        }
      }
    }

    copy_to 属性 允许我们将多个字段的值复制到组字段中,然后将组字段作为单个字段进行查询。

    #把 first_name last_name copy到full_name里
    PUT m5
    {
      "mappings": {
        "doc": {
          "dynamic":false,
          "properties": {
            "first_name":{
              "type": "text",
              "copy_to": "full_name"
            },
            "last_name": {
              "type": "text",
              "copy_to": "full_name"
            },
            "full_name": {
              "type": "text"
            }
          }
        }
      }
    }
    
    PUT m5/doc/1
    {
      "first_name":"tom",
      "last_name":"ben"
    }
    
    PUT m5/doc/2
    {
      "first_name":"john",
      "last_name":"smith"
    }
    
    GET m5/doc/_search
    {
      "query": {
        "match": {
          "first_name": "tom"
        }
      }
    }
    
    GET m5/doc/_search
    {
      "query": {
        "match": {
          "full_name": "tom"
        }
      }
    }
    
    
    GET m5/doc/_search  #可以查询到2条数据
    {
      "query": {
        "match": {
          "full_name": "tom smith"
        }
      }
    }

     settings设置

    number_of_shards是主分片数量(每个索引默认5个主分片),而number_of_replicas是复制分片,默认一个主分片搭配一个复制分片。

    PUT w2
    {
      "mappings": {
        "doc":{
          "properties":{
            "title":{
              "type":"text"
            }
          }
        }
      },
      "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 3
      }
    }

    python 基本操作 elasticsearch 

    from elasticsearch import Elasticsearch
    es = Elasticsearch()
    print(es.index(index='p1', doc_type='doc', id=1, body={"name":"lou"}))
    print(es.get(index='p1', doc_type='doc', id=1))
    print(es.delete(index='p1', doc_type='doc', id=2))
    #修改
    print(es.index(index='p1', doc_type='doc', id=1, body={"name":"lou2"}))
    
    
    def filter_msg(search_msg, target, current_page):
    if target == 'all':
    # print(target)
    body = {
    "size": 200,
    "query": {
    "match": {
    "title": search_msg,
    }
    },
    "highlight": {
    "pre_tags": "<b style='color:red;'>",
    "post_tags": "</b>",
    "fields": {
    "title": {}
    }
    }
    }
    else:
    body = {
    "size": 200,
    "query": {
    "bool": {
    "must": [{"match": {
    "title": search_msg,
    }
    }, {
    "match": {
    "tags": target,
    }}
    ]
    }

    },
    "highlight": {
    "pre_tags": "<b style='color:red;'>",
    "post_tags": "</b>",
    "fields": {
    "title": {}
    }
    }
    }
    res = es.search(index='e1', body=body, filter_path=['hits.total', 'hits.hits'])
    page_obj = Pagination(current_page, res['hits']['total'])
    print(1111, res)
    res['page'] = page_obj.show_li
    res['data_msg'] = res['hits']['hits'][page_obj.start:page_obj.end]
    res['hits']['hits'] = ''
    return res
    views 文件
    def search(request):
        if request.method == 'GET':
            search_msg = request.GET.get("search_msg")
            target = request.GET.get("target")
            current_page = request.GET.get('current_page')
            print(target, '1111', current_page)
            res = filter_msg(search_msg, target, current_page)
            return JsonResponse(res)
        return render(request, 'index.html')
     
  • 相关阅读:
    正确使用Core Data多线程的3种方式
    iOS开发周报:新一代 iPhone 可能取消耳机插口,Facebook 发布 tvOS SDK
    Atomic:Android、iOS和网页的设计工具
    iOS应用架构谈(三):View层的组织和调用方案(下)
    SQL server 2008数据库的备份与还原(转)
    重定向技术
    Python 正则表达式应用【转载】
    Fidder 工具使用
    HTTP请求大全
    RobotFramework环境搭建
  • 原文地址:https://www.cnblogs.com/zaizai1573/p/10903311.html
Copyright © 2011-2022 走看看