ElasticSearch操作文档
什么是ES中的文档?
document --存放数据
在ES里面通过index索引库type 类型(表)行({id:name:}) 列 id /name
ES是面向文档(Document Oriented)的,这意味着它可以存储整个对象或文档(document)。然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜索。在ES中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。
ES使用Javascript对象符号(JavaScript Object Notation),也就是JSON,作为文档序列化格式。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------一个文档不只有数据。它还包含元数据(metadata)—关于文档的信息。三个必须的元数据节点是:
_index:索引库,类似于关系型数据库里的“数据库”—它是我们存储和索引关联数据的地方。
_type:在应用中,我们使用对象表示一些“事物”,例如一个用户、一篇博客、一个评论,或者一封邮件。可以是大写或小写,不能包含下划线或逗号。我们将使用 employee 做为类型名。
_id:与 _index 和 _type 组合时,就可以在ELasticsearch中唯一标识一个文档。当创建一个文档,你可以自定义 _id ,也可以让Elasticsearch帮你自动生成。
另外还包括:_uid文档唯一标识(_type#_id)
_source:文档原始数据
_all:所有字段的连接字符串
========================================================================================================================
下面我们具体操作一下
ES文档的实际操作
ES简单查询
## 查询crm库下面的其中一个goods表的所有数据
#match_all表示全匹配
GET shop/goods/_search
{
"query": {
"match_all": {}
}
}
##新增数据并且指定id
PUT shop/goods/11
{
"name":"iphonex",
"pirce":11000,
"address":"cn"
}
#查询所有
GET shop/goods/_search
#简化版查询
GET _search
#批量查询:以数组的形式将id放入
GET shop/goods/_mget
{
"ids":["1","2"]
}
#分页查询:size表示每页多少条.from:从那个地方开始
GET shop/goods/_search?size=3&from=0
# 条件查询-条件较少的情况下 q代表查询条件
GET shop/goods/_search?q=address:cn
GET shop/goods/_search?q=price[1000 TO 5000] &from=0&size=2
ES文档 DSL语言查询
注意:
DSL有两部分组成:DSL查询和DSL过滤
DSL查询类似于 mysql中的模糊查询
DSL过滤则像是精确查询,“有"或"没有”
接下来 我们实际来操作下
#DSL查询(模糊查询)-适用于条件比较多的
#----------------------------------------------------------------
#match:表示 完全匹配,即根据字段查询出匹配的数据
GET shop/goods/_search
{
"query": {
"match": {
"name": "iphonex"
}
}
}
# 通配符查询:使用*代表0~N个,使用?代表1个。
GET shop/goods/_search
{
"query":{
"wildcard": {
"name":"iph*ne"
}
}
}
# 前匹配搜索与过滤(prefix)
GET shop/goods/_search
{
"query": {
"prefix": {
"address":"c"
}
}
}
#范围查询:(gt> lt< gte>= lte<=)
GET shop/goods/_search
{
"query": {
"range": {
"pirce": {
"gte": 5000,
"lte": 10000
}
}
}
}
# multi_match查询允许一个查询条件,多个字段匹配
GET shop/goods/_search
{
"query": {
"multi_match": {
"query": "cn",
"fields": ["name","address"]
}
}
}
# 单词搜索与过滤(Term和Terms)
GET shop/goods/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"term": {
"name": "iphone"
}
}
}
}
}
GET shop/goods/_search
{
"query": {
"terms": {
"name": ["iphone", "iphonex"]
}
}
}
#测试分词
POST _analyze
{
"analyzer":"ik_smart",
"text":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
}
#DSL查询
GET shop/goods/_search
{
"query": {
"match_all":{}
},
"from": 0,
"size": 3,
"_source": ["name", "pirce", "address"],
"sort":[{"price":"desc"}]
}
# DSL过滤查询:filter
#must(英文:必须):关键字,term:单词搜索与过滤,分页,排序,
GET shop/goods/_search
{
"query":{
"bool": {
"must": [
{"match": {"name":"iphone"}}
],
"filter": {
"term": {
"pirce": "1000"
}
}
}
},
"from":0,
"size":3,
"_source":["name","pirce","address"],
"sort":[{"pirce":"desc"}]
}
## 题目:查询关键字iphone,查询最高价格的前两条,查询 地区cn,且价格范围在7000-9000
#注意:filter是过滤条件
#term:代表 等值过滤 的意思,即选定了某个条件就进行过滤
GET shop/goods/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "iphone"
}
}
],
"filter": [
{"term": {"address": "cn"}},
{"range": {"pirce": {"gte": 7000,
"lte": 9000}}}]}},
"from": 0,
"size": 3,
"sort": [
{
"pirce": {
"order": "desc"
}
}
],
"_source": ["name","pirce","address"]
}
ik分词器
ES默认对英文文本的分词器支持较好,但和lucene一样,如果需要对中文进行全文检索,那么需要使用中文分词器,同lucene一样,在使用中文全文检索前,需要集成IK分词器。
① Maven打包IK插件
② 解压target/releases/elasticsearch-analysis-ik-5.2.2.zip文件
并将其内容放置于ES根目录/plugins/ik
例如:本人的a安装目录:D:\JavaSoftware\elasticsearch-5.2.2\plugins\ik
JAVA API(重点)
啥是Java API?
ES对Java提供一套操作索引库的工具包,即Java API。所有的ES操作都使用Client对象执行。
ES对java客户端的实操
1、导包
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
2、连接ES获取Client对象
设置client.transport.sniff为true来使客户端去嗅探整个集群的状态,把集群中其它机器的ip地址加到客户端中,这样做的好处是一般你不用手动设置集群里所有集群的ip到连接客户端,它会自动帮你添加,并且自动发现新加入集群的机器。
// 获取客户端对象
public TransportClient getClient() throws Exception {
Settings settings = Settings.builder()
.put("client.transport.sniff", true)
.put("cluster.name", "my-elasticsearch").
build();
TransportClient client = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301));
return client;
}
3、新增和修改
//ES测试增和改:因为ES文档修改数据时是以 先删除在增加的形式来修改数据
@Test
public void save() throws Exception {
IndexRequestBuilder indexRequestBuilder = getClient().prepareIndex("emp", "user", "1");
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "ymq");
map.put("age", 22);
indexRequestBuilder.setSource(map);
IndexResponse indexResponse = indexRequestBuilder.get();
System.err.println(indexResponse);
}
5、查询数据
//查询数据
@Test
public void query() throws Exception {
GetRequestBuilder getRequestBuilder = getClient().prepareGet("emp", "user", "1");
GetResponse getFields = getRequestBuilder.get();
System.err.println(getFields);
}
6、删除数据
//删除数据
@Test
public void delete() throws Exception {
DeleteRequestBuilder deleteRequestBuilder = getClient().prepareDelete("emp", "user", "1");
DeleteResponse deleteResponse = deleteRequestBuilder.get();
System.err.println(deleteRequestBuilder);
}
ES模拟淘宝搜索商品(通过数据)
这里就直接上代码了!
首先 我们得创建一个索引库和一张表,并且往里面添加数据
//创建一个库和表,并且批量添加数据
@Test
public void bluk() throws Exception{
BulkRequestBuilder bulkRequest = getClient().prepareBulk();
for (int i = 0; i <10; i++) {
IndexRequestBuilder indexRequestBuilder = getClient().prepareIndex("shop", "goods", i + "");
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "iphone");
map.put("address", "cn");
map.put("price", i*1000);
indexRequestBuilder.setSource(map);
bulkRequest.add(indexRequestBuilder);
}
// 批量请求
BulkResponse bulkResponse = bulkRequest.get();
if (bulkResponse.hasFailures()) {
//处理错误
System.err.println("批量失败");
}
}
其次,我们就该开始进行查询数据了
给自己设定一个题目把
题目:查询关键字iphone,查询最高价格的前两条,查地#查询 di区cn,且价格范围在7000-9000
@Test
public void search() throws Exception {
//获取客户端中的shop库中的goods表中的数据进行排序和分页
SearchRequestBuilder searchRequestBuilder = getClient().prepareSearch("shop").setTypes("goods").addSort("price", SortOrder.DESC).setSize(3).setFrom(0);
//查询条件
BoolQueryBuilder bool = new BoolQueryBuilder();
//关键字匹配
bool.must(new MatchQueryBuilder("name","iphone"));
//过滤条件
List<QueryBuilder> filter = bool.filter();
filter.add(new TermQueryBuilder("address", "cn"));
filter.add(new RangeQueryBuilder("price").gte(7000).lte(9000));
searchRequestBuilder.setQuery(bool);
//执行操作
SearchResponse searchResponse = searchRequestBuilder.get();
//ES文档里面的数据存储在hits(json对象)中的hits数组中,所以我们需要取两次,并且循环遍历里面的数据
SearchHit[] hits = searchResponse.getHits().getHits();
for (SearchHit hit:hits) {
System.err.println(hit.getSource());
}
}