ES 数据库


熟悉 es 的同学都知道 es 一般有两种查询方式

1,在 java 中构建查询对象,调用 es 提供的 api 做查询
2,使用 json 调用接口做查询

查询语句无非是将足够的信息丢给数据库,但是它却和 SQL 不一样有自己独立的查询方式

通过 API 查询

模糊查询

BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();

//Elasticsearch 中文会把汉字分词,“王大”会匹配到like“王”和like“大”,要在字段后面接keyword
boolBuilder.must(QueryBuilders.wildcardQuery("userName.keyword","*王大*"));

等于、不等于

BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
//等于  must
boolBuilder.must(QueryBuilders.termQuery("age","30"));
//不等于  mustNot
boolBuilder.mustNot(QueryBuilders.termQuery("sex","1"));

大于、小于

BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
//大于
boolBuilder.must(QueryBuilders.rangeQuery("createTime").gt(1609430400000));
//小于
boolBuilder.must(QueryBuilders.rangeQuery("createTime").lt(1672502400000));

es 也是有层级的,下面演示 and 、or 同时使用

BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
 
boolBuilder.must(QueryBuilders.termQuery("a",1));
 
QueryBuilder queryBuilder1 = QueryBuilders.boolQuery()
                    .must(QueryBuilders.termQuery("b", 2))
                    .must(QueryBuilders.termQuery("c", 3))
                    .mustNot(QueryBuilders.termQuery("d", 4));
 
QueryBuilder queryBuilder2 = QueryBuilders.boolQuery()
                    .must(QueryBuilders.termQuery("e", 4))
                    .must(QueryBuilders.termQuery("f", 5));
 
QueryBuilder queryBuilder = QueryBuilders.boolQuery()
                    .should(queryBuilder1)
                    .should(queryBuilder2);
 
boolBuilder.must(queryBuilder);

等同与这个 sql

select * from user where a=1 and ((b=2 and c=3 and d !=4) or (e=4 and f=5))

通过 JSON 查询

我们需要先知道 es 的地址,然后看看他存在哪些索引

-- 访问所有索引信息
curl -X GET http://localhost:9200/_cat/indices?v
-- 添加索引
curl -X PUT http://localhost:9200/demo
-- 访问索引
curl -X GET http://localhost:9200/demo
-- 删除索引
curl -X DELETE http://localhost:9200/demo
-- 给索引添加文档数据
curl -X POST http://localhost:9200/demo/_doc -d "{\"name\": \"hello\"}" -H "content-type: application/json; charset=UTF-8"

接下来聊一下他的 SQL,我们需要在索引后面加 /_search 来访问他的数据,get 和 post 都可以来查询

curl -X GET http://localhost:9200/demo/_search?q=name:wang
curl -X GET http://localhost:9200/demo/_search -d "{请求体}" -H "content-type: application/json; charset=UTF-8"

相信这个简单的查询大家都可以看出是查 name 字段等于 wang 的数据,接下来我们把他扩充一下。下面的 from 参数表示从第几条数据开始;size 参数表示获取多少条数据;query 表示查询,match 表示匹配,里面填写要匹配的字段值

{
	"query": {
		"match": {
			"name": "wang"
		},
		"from": 0,
		"size": 1
	}
}

是不是很简单,我们加个速,多条件查询如下

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "name": "wang"
                    }
                },
                {
                    "match": {
                        "age": 10
                    }
                }
            ],
            "should": [
                {
                    "match": {
                        "name": "andy"
                    }
                }
            ]
        }
    }
}

query 参数表示查询,bool 参数表示查询的条件,里面填写要查询的条件;must 参数表示多个条件要同时成立,里面填写条件列表,相当于 AND 的意思,而 should 表示 OR,上面的 must 和 should 是同级的

match 和 bool 有一些区别,当在 match 子句中仅使用一个条件查询时,则没有区别,当想要组合多个条件时,bool 子句很有用

范围查询,查询年龄大于等于18,并且小于等于50的数据,include_lower 代表包含下界,include_upper 代表包含上界。如果有多个条件的话,范围查询只需要在 bool 条件下添加 filter 参数即可,参数里面可以填写多个过滤条件

{
    "query": {
        "range": {
            "age": {
                "include_lower": true,
                "include_upper": true,
                "from": 18,
                "to": 50
            }
        }
    }
}

ES 实现

ElasticSearch 是面向文档的非关系型数据库,elasticsearch 集群中可以包含多个索引(es 数据库,es 进程),每个索引中可以包含多个分片(表),每个类型下又包含多个文档(行)。其实可以把 es 理解成多个倒排索引的聚合

elasticsearch 在后台把每个索引划分成多个分片,每份分片可以在集群中的不同服务器间迁移

一个索引类型中,包含多个文档,比如说文档1,文档2。 当我们索引一篇文档时,可以通过这样的一个顺序找到它: 索引 ▷ 类型 ▷ 文档 ID ,通过这个组合我们就能索引到某个具体的文档。 注意 : ID不必是整数,实际上它是个字符串

文档:之前说 elasticsearch 是面向文档的,那么就意味着索引和搜索数据的最小单位是文档,elasticsearch 中,文档有几个重要属性

  • 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含 key:value!在 elk 中,我们存放日志的时候就是将一条日志作为 v 来存放的
  • 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的!其实就是个 JSON 对象
  • 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在 elasticsearch 中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段
  • 尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类型,可以是字符串也可以是整形。因为 elasticsearch 会保存字段和类型之间的映射及其他的设置。这种映射具体到每个映射的每种类型,这也是为什么在 elasticsearch 中,类型有时候也称为映射类型

索引是映射类型的容器,elasticsearch 中的索引是一个非常大的文档集合。索引存储了映射类型的字段和其他设置。 然后它们被存储到了各个分片上了

一个集群至少有一个节点,而一个节点就是一个 elasricsearch 进程,节点可以有多个索引,如果你创建索引,那么索引将默认会有个5个分片(primary shard,又称主分片) 构成的,每一个主分片会有一个副本(replica shard ,又称复制分片)

下图是一个有3个节点的集群,可以看到主分片和对应的复制分片都不会在同一个节点内,这样有利于某个节点挂掉了,数据也不至于丢失

在这里插入图片描述
实际上,一个分片是一个 Lucene 索引,一个包含倒排索引的文件目录,倒排索引的结构使得 elasticsearch 在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字

ElasticSearch 是基于 Lucene 的,那么为什么不是直接使用 Lucene 呢?Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库。但是 Lucene 仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中。 更糟糕的是,您可能需要获得信息检索学位才能了解其工作原理。Lucene 非常 复杂。Elasticsearch 也是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单,通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值