ElasticSearch 是一个基于Lucene的实时的分布式搜索和分析引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。Elasticsearch的架构原理,底层也是大量基于os cache实现了海量数据的高性能检索的,跟Kafka原理类似(Kafka完全基于内存提供数据的写和读了,所以这个整体性能会极其的高——零拷贝技术)。

一、Es和solr百度指数对比

es sort和boost冲突 es和solr区别_elasticsearch

ElasticSearch vs Solr 总结:

(1)es基本是开箱即用,非常简单。Solr安装较复杂。
(2)Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 还可以用自身带有分布式协调管理功能。
(3)Solr 支持更多格式的数据,比如JSON、XML、CSV,而 Elasticsearch 仅支持json文件格式。
(4)Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供,例如图形化界面需要kibana友好支撑
(5)Solr 查询快,但更新索引时慢(即插入删除慢),用于电商等查询多的应用;
     ES建立索引快,即实时性查询快,用于facebook新浪等搜索。
     Solr 是传统搜索应用的有力解决方案,但 Elasticsearch 更适用于新兴的实时搜索应用。
(6)Solr比较成熟,有成熟的用户、开发和贡献者社区,而 Elasticsearch相对开发维护者较少,更新太快,Solr官网提供的功能更多,而es本身更注重于核心功能,高级功能多有第三方插件。

二、Elasticsearch的核心概念

名称

含义

对应在mysql中的含义

index

索引

数据库

type

类型


document

文档


fields

字段


  1. 索引(Index)—— Elasticsearch索引是一组具有共同特征的文档集合。每个索引(index)包含多个类型(type),这些类型依次包含多个文档(document),每个文档包含多个字段(Fields)。在Elasticsearch中索引由多个JSON文档组成。在Elasticsearch集群中可以有多个索引。在ELK中,当logstash的JSON文档被发送给Elasticsearch时,它们被发送为默认的索引模式“logstash-%{+YYYY.mm.dd}”。它按日划分索引,以便在需要时可以方便地搜索和删除索引。这个模式可以在日志存储的输出插件中改变。
  2. 类型(Type)
  3. 文档(document)
  4. 字段(Field)
  5. 映射(Mapping) —— 映射用于映射文档的每个field及其对应的数据类型,例如字符串、整数、浮点数、双精度数、日期等等。在索引创建过程中,elasticsearch会自动创建一个针对fields的映射,并且根据特定的需求类型,可以很容易地查询或修改这些映射。
  6. 分片(Shard) ——分片是实际的物理实体用于存储每个索引的数据。每个索引都可以有大量的主和复制分片。分片分布在集群中的所有节点中,可以在节点故障或新节点添加时从一个节点移动到另一个节点。
  7. 主分片(Primary shard)与备份分片(replica shard) —— 备份分片通常驻留在一个不同的节点上,而不是主碎片,在故障转移和负载平衡的情况下,可以满足多个请求。
  8. 集群(Cluster) —— 集群是存储索引数据的节点集合。elasticsearch提供了水平的可伸缩性用以存储集群中的数据。每个集群都由一个集群名称来表示,不同的节点指明集群名称连接在一起。集群名称在elasticsearch.yml中的clustersearch.name的属性设置,它默认为“elasticsearch”:
  9. 节点(Node) —— 节点是一个单独运行的elasticsearch实例,它属于一个集群。默认情况下,elasticsearch中的每个节点都加入名为“elasticsearch”的集群。每个节点都可以在elasticsearch中使用自己的elasticsearch.yml,它们可以对内存和资源分配有不同的设置。
  10. 底层为Lucene —— file(文件)>segment(段,多个document组成)>document(一条记录,一个对象实例)>field(对象的属性)>term(项,分词之后的词条)

三、Elasticsearch API详解

3.1、ES内置的REST接口

es sort和boost冲突 es和solr区别_json_02

3.2  内置API 增删功能

API基本格式:  http:// <ip>:<port>/<索引index>/<类型type>/<文档id>

  • 索引创建:curl -XPUT http://192.168.18.103:9200/lxk/
  • 删除索引:curl -XDELETE http://192.168.18.103:9200/lxk/
  • 插入类型和行:
#document:yes 
curl -XPOST -H 'content-Type:application/json' http://192.168.18.103:9200/snlxk/employee -d '
{
 "first_name" : "bin",
 "age" : 33,
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ]
}'

# 新增一行
curl -XPOST -H 'content-Type:application/json' http://192.168.18.103:9200/snlxk/employee -d '
{
 "first_name" : "gob bin",
 "age" : 43,
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ]
}'

# 指定某一行数据
curl -XPOST -H 'content-Type:application/json' http://192.168.18.103:9200/snlxk/employee/2 -d '
{
 "first_name" : "bin",
 "age" : 45,
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ]
}'
  • 插入field:
#add field yes

curl -XPOST -H 'content-Type:application/json' http://192.168.18.103:9200/snlxk/employee -d '
{
 "first_name" : "pablo2",
 "age" : 33,
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ],
 "sex": "man"
}'

curl -XPOST -H 'content-Type:application/json' http://192.168.18.103:9200/snlxk/employee/1 -d '
{
 "first_name" : "pablo2",
 "age" : 35,
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ],
 "sex": "man"
}'
  •  使用put命令插入:(实测和post一样)
#put:yes


curl -XPUT -H 'content-Type:application/json' http://192.168.18.103:9200/snlxk/employee/1 -d '
{
 "first_name" : "god bin",
 "last_name" : "pang",
 "age" : 42,
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ]
}'

curl -XPUT -H 'content-Type:application/json' http://192.168.18.103:9200/snlxk/employee -d '
{
 "first_name" : "god bin",
 "last_name" : "bin",
 "age" : 45,
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ]
}'


curl -XPUT -H 'content-Type:application/json' http://192.168.18.103:9200/snlxk/employee/2 -d '
{
 "first_name" : "god bin",
 "last_name" : "bin",
 "age" : 45,
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ]
}'

curl -XPUT -H 'content-Type:application/json' http://192.168.18.103:9200/snlxk/employee/1 -d '
{
 "first_name" : "god bin",
 "last_name" : "pang",
 "age" : 40,
 "about" : "I love to go rock climbing",
 "interests": [ "sports", "music" ]
}'

网页查看结果: 

es sort和boost冲突 es和solr区别_json_03

3.3  内置API  查询功能

  • 根据document的id来获取数据:(without pretty)  curl -XGET http://192.168.18.103:9200/snlxk/employee/1?pretty

es sort和boost冲突 es和solr区别_elasticsearch_04

  • 根据field来查询数据:curl -XGET http://192.168.18.103:9200/snlxk/employee/_search?q=first_name="bin"

根据field来查询数据:match 

curl -XGET http://192.168.18.103:9200/snlxk/employee/_search?pretty -d '
{
 "query":
  {"match":
   {"first_name":"bin"}
  }
}'

对多个field发起查询:multi_match

curl -XGET http://192.168.18.103:9200/snlxk/employee/_search?pretty -d '
{
 "query":
  {"multi_match":
   {
    "query":"bin",
    "fields":["last_name","first_name"],
    "operator":"and"
   }
  }
}'
  • 多个term对多个field发起查询:bool(boolean) 
  1. # 组合查询,must,must_not,should 
  • #  must + must : 交集
  • #  must +must_not :差集
  • #  should+should  : 并集
curl -XGET http://192.168.18.103:9200/snlxk/employee/_search?pretty -d '
{
 "query":
  {"bool" :
   {
    "must" : 
     {"match":
      {"first_name":"bin"}
     },
    "must" : 
     {"match":
      {"age":33}
     }
   }
  }
}'
curl -XGET http://192.168.18.103:9200/snlxk/employee/_search?pretty -d '
{
 "query":
  {"bool" :
   {
    "must" : 
     {"match":
      {"first_name":"bin"}
     },
    "must_not" : 
     {"match":
      {"age":33}
     }
   }
  }
}'

 查询first_name=bin的,但是年龄不在20岁到33岁之间的

curl -XGET http://192.168.18.103:9200/snlxk/employee/_search -d '
{
 "query":
  {"bool" :
   {
   "must" :
    {"term" : 
     { "first_name" : "bin" }
    }
   ,
   "must_not" : 
    {"range":
     {"age" : { "from" : 20, "to" : 33 }
    }
   }
   }
  }
}'
  •  设置主分片和每个分片的副本数(默认是一个索引库有5个分片,总数为:副本数+1)
curl -XPUT 'http://192.168.18.103:9200/test2/' -d'{"settings":{"number_of_replicas":2}}'

curl -XPUT 'http://192.168.18.103:9200/test3/' -d'{"settings":{"number_of_shards":3,"number_of_replicas":3}}'

curl -XPUT 'http://192.168.18.103:9200/test4/' -d'{"settings":{"number_of_shards":6,"number_of_replicas":4}}'
curl -XPOST http://192.168.9.11:9200/snlxk/person/_mapping -d'
{
    "person": {
        "properties": {
            "content": {
                "type": "string",
                "store": "no",
                "term_vector": "with_positions_offsets",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word",
                "include_in_all": "true",
                "boost": 8
            }
        }
    }
}'

高级检索语法:term, wildcard, prefix, fuzzy, range, query_string, text, missing

  • term:严格匹配条件,所查询的字段内容要与填入查询框搜索值一致;
  • wildcard:通配符查询,* 表示全匹配,? 表示单一匹配,etc: aaa* 或者 a?b;
  • prefix:前缀匹配,搜索框如果输入aa,那么可能匹配到的字段值为 aab,aavb等;
  • fuzzy min_similarity:弹性模糊匹配,有两个搜索框,第一个搜索框为搜索匹配值,会自动纠错,比如输入 ggjk,那么可能会匹配到ggjo,第二个框为最小相似度,采用的算法是Damerau-Levenshtein(最佳字符串对齐)算法,不建议填写这个框,我到发稿前也是被搞的头皮发麻,等我完全吃透再更新;
  • fuzzy max_expansions :弹性模糊匹配,有两个搜索框,第一个搜索框为搜索匹配值,会自动纠错,比如输入 ggjk,那么可能会匹配到ggjo,第二个框是最大扩展匹配数,比如是1,那么ggjk只会随机模糊匹配到一种可能结果,即使它会出现2种或者更加多,也只会搜索一种;
  • range:范围查询,gt为大于,gte为大于等于,lt小于,lte小于等于,所搜索的字段值在两个搜索框标识数值之间;
  • query_string:字符片段查询,如果是数字,则严格匹配数字,如果是字符串,则按照自身或者分片词匹配;
  • text:分片词查询,等确定后更新;
  • missing:查询没有定义该字段或者该字段值为null的数据。