ES API基础

ES基本使用
package com.paic;

import java.net.InetAddress;
import java.text.MessageFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import com.google.gson.Gson;

public class ElasticSearchTester {
	public static String INDEX = "oms";
	public static String TYPE = "order";

	public static TransportClient client;
	static {
		try {
			Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();
			client = new PreBuiltTransportClient(settings);
			client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
			System.out.println("---ES连接成功!---");
			
			if(! client.admin().indices().exists(new IndicesExistsRequest(INDEX)).actionGet().isExists()){
				creatIndex();
//				{
//				    "id": 2, 
//				    "order_no": "OB-755679845", 
//				    "product": "SE0033", 
//				    "warehouse": "7550VB", 
//				    "items": 120, 
//				    "container": "379900890889765", 
//				    "createTime": "Oct 2, 2019 4:22:56 PM"
//				}
				creatIndexByBuilder("1", "OB-755677823", "SE0001", "7550VB", 50, null);
				creatIndexByBuilder("2", "OB-755679845", "SE0033", "7550VB", 180, "2346986");
				creatIndexByBuilder("3", "IN-755673490", "SE0001", "010VSB", 130, null);
				creatIndexByBuilder("4", "OB-785677343", "SE0033", "DXD_WH", 30, null);
				creatIndexByBuilder("5", "IN-785677343", "SE0033", "DXD_WH", 90, "2346524");
//				POST http://localhost:9200/oms/order
//				{\"id\":1,\"order_no\":\"OB-755677823\",\"product\":\"SE0001\",\"warehouse\":\"7550VB\",\"items\":50,\"createTime\":\"Oct 2, 2019 4:32:46 PM\"}{\"id\":2,\"order_no\":\"OB-755679845\",\"product\":\"SE0033\",\"warehouse\":\"7550VB\",\"items\":120,\"container\":\"379900890889765\",\"createTime\":\"Oct 2, 2019 4:22:56 PM\"}{\"id\":3,\"order_no\":\"IN-755673490\",\"product\":\"SE0001\",\"warehouse\":\"010VB\",\"items\":80,\"createTime\":\"Oct 2, 2019 4:30:46 PM\"}{\"id\":4,\"order_no\":\"OB-785677343\",\"product\":\"SE0033\",\"warehouse\":\"DXD_WH\",\"items\":150,\"createTime\":\"Oct 2, 2019 6:32:46 PM\"}{\"id\":5,\"order_no\":\"IN-785677343\",\"product\":\"SE0033\",\"warehouse\":\"DXD_WH\",\"items\":150,\"container\":\"379900890990232\",\"createTime\":\"Oct 2, 2019 6:32:46 PM\"}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws Exception {
		// creatIndex();
		// creatIndexByBuilder();
		// getMultiData();
		// matchAllQuery();
//		query_2();
		query_3();
	}
	
	public static void query_2() {
		BoolQueryBuilder builder = QueryBuilders.boolQuery();

		// WHERE product='SE0001'
		// builder.must(QueryBuilders.matchQuery("product", "SE0001"));

		// WHERE product='SE0001' and order_no 包含'OB'
		builder.must(QueryBuilders.matchQuery("product", "SE0001"));
		builder.must(QueryBuilders.matchQuery("order_no", "OB"));

		// WHERE warehouse='010VB' or (warehouse ='7550VB' and product='SE0033')
//		builder.should(QueryBuilders.matchQuery("warehouse", "010VSB"));
//		builder.should(QueryBuilders.boolQuery()
//				.must(QueryBuilders.matchQuery("warehouse", "7550VB"))
//				.must(QueryBuilders.matchQuery("product", "SE0033")));

		// WHERE container != null or (warehouse='010VSB' or items > 130)
//		builder.should(QueryBuilders.existsQuery("container"));
//		builder.should(QueryBuilders.boolQuery()
//				.should(QueryBuilders.matchQuery("warehouse", "010VSB"))
//				.should(QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery("items").gte(130))));//gt: > gte: >=  lt: <  lte: <= 
		
		SearchRequestBuilder reqBuilder = client.prepareSearch(INDEX).setTypes(TYPE).setQuery(builder);
		SearchResponse searchResponse = reqBuilder.get();
		SearchHits hits = searchResponse.getHits();// 获取命中数,查询结果有多少对象
		System.out.println("参数:\n"+reqBuilder.toString());
		System.out.println("查询到" + hits.totalHits + "条");
		for (SearchHit hit : hits) {
			System.out.println(hit.getSourceAsString());
		}
	}

	public static void query_3() {
		SearchRequestBuilder sbuilder = client.prepareSearch(INDEX).setTypes(TYPE);
		TermsAggregationBuilder teamAgg= AggregationBuilders.terms("product_count").field("product");
	    sbuilder.addAggregation(teamAgg);
	    SearchResponse response = sbuilder.execute().actionGet();
	    System.out.println(response);
	    StringTerms terms = response.getAggregations().get("product_count");
	    Iterator<StringTerms.Bucket> teamBucketIt = terms.getBuckets().iterator();
        while (teamBucketIt .hasNext()) {
            Terms.Bucket bucket = teamBucketIt.next();
            String team = (String) bucket.getKey();
            long count = bucket.getDocCount();
            System.out.println(team + " " + count);
        }
	}

	public static void creatIndex() {
		client.admin().indices().prepareCreate(INDEX).get();
	}

	public static void creatIndexByBuilder(String id, String orderNo, String product, String warehouse, int items, String container) {
		try {
			XContentBuilder builder = XContentFactory.jsonBuilder()
					.startObject()
					.field("id", id)
					.field("order_no", orderNo)
					.field("product", product)
					.field("warehouse", warehouse)
					.field("items", items)
					.field("container", container)
					.field("createTime", new Date())
					.endObject();
			IndexResponse indexResponse = client.prepareIndex(INDEX, TYPE, null).setSource(builder).execute()
					.actionGet();
			
			System.out.println(MessageFormat.format("[index:{0}] [type:{1}] [id:{2}] [version:{3}] [result:{4}]",
					indexResponse.getIndex(), indexResponse.getType(), indexResponse.getId(), indexResponse.getVersion(),
					indexResponse.getResult()));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Map<String, Object> jsonDoc = new HashMap<String, Object>();
	 * jsonDoc.put("id", "2"); jsonDoc.put("title", "基于Lucene的搜索服务器");
	 * jsonDoc.put("content", "它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口");
	 */
	public static void creatIndexByMap(Map<String, Object> jsonDoc) {
		IndexResponse indexResponse = client.prepareIndex(INDEX, TYPE, null).setSource(jsonDoc).execute().actionGet();
		// 3、打印返回的结果
		System.out.println(MessageFormat.format("[index:{0}] [type:{1}] [id:{2}] [version:{3}] [result:{4}]",
				indexResponse.getIndex(), indexResponse.getType(), indexResponse.getId(), indexResponse.getVersion(),
				indexResponse.getResult()));
	}

	public static void getMultiData() {
		// 1、查询多个文档
		MultiGetResponse response = client.prepareMultiGet().add(INDEX, TYPE, "1").add(INDEX, TYPE, "2", "3")
				.add(INDEX, TYPE, "2").get();
		// 2、遍历返回的结果
		for (MultiGetItemResponse itemResponse : response) {
			GetResponse getResponse = itemResponse.getResponse();
			// 如果获取到查询结果
			if (getResponse.isExists()) {
				String sourceAsString = getResponse.getSourceAsString();
				System.out.println(sourceAsString);
			}
		}
	}

	public static void matchAllQuery() {
		// 1.执行查询(查询所有)
		SearchResponse searchResponse = client.prepareSearch(INDEX).setTypes(TYPE)
				.setQuery(QueryBuilders.matchAllQuery()).get();
		// 2、打印查询结果
		SearchHits hits = searchResponse.getHits();// 获取命中数,查询结果有多少对象
		System.out.println("查询结果一共有" + hits.totalHits + "条");
		for (SearchHit hit : hits) {
			System.out.println(hit.getSourceAsString());
		}
	}


}
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>5.6.0</version>
</dependency>

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>transport</artifactId>
    <version>5.6.0</version>
</dependency>
ES映射

为了能够将时间域视为时间,数字域视为数字,字符串域视为全文或精确值字符串, Elasticsearch 需要知道每个域中数据的类型。这个信息包含在映射中,索引中每个文档都有类型 。每种类型都有它自己的映射

ES支持如下域类型:

简单类型

  • 字符串: string

  • 整数 : byte, short, integer, long

  • 浮点数: float, double

  • 布尔型: boolean

  • 日期: date

    复杂类型

  • 对象数据类型: object,单独的JSON对象。

  • 嵌套数据类型: nested,关于JSON对象的数组。

    地理类型

  • 经纬度

    • 查找一定范围内的地理点,这个范围可以是相对于一个中心点的固定距离,也可以是多边形或者地理散列单元
    • 通过地理位置或者相对于中心点的距离聚合文档
    • 通过距离对文档进行排序

    专门数据类型

  • IPv4数据类型

    • IPv4字段本质上是一个长整型字段,接受IPv4地址并作为长整型值进行索引(192.168.0 -> 1921680)

默认提供了以下映射规则(动态映射),新增文档时,会根据值类型按下面的规则进行猜测,比如{“age”:“25”}会将age视为字符串类型,{“age”:25}会将age视为数字类型。映射操作会在文档的每个层级都会做,即嵌套很多层对JSON一样可以被映射

JSON type域 type
布尔型: true 或者 falseboolean
整数: 123long
浮点数: 123.45double
字符串,有效日期: 2014-09-15date
字符串: foo barstring

创建一个索引

localhost:9200/map/order

{"id":1,"tag":"java技术博客","author":"bob","createTime":"2014-09-15","content":{"title":"ES的基本使用","theme":"黑礁石主题","rows":150,"body":{"data":"ES搜索引擎是为解决传统搜索工具易用性问题,应用广泛","quote":["http://www.baidu.com/","http://www.sina.com"]}}}

查看映射

localhost:9200/map/_mapping/order

{"map":{"mappings":{"order":{"properties":{"author":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"content":{"properties":{"body":{"properties":{"data":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"quote":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},"rows":{"type":"long"},"theme":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"title":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},"createTime":{"type":"date"},"id":{"type":"long"},"tag":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}}}}

即使没有加映射也会按默认规则进行映射,并且嵌套层级节点也会被映射到

多层级JSON对象实际上会被映射成键值对形式(因为Lucene不理解内部对象。 Lucene文档是由一组键值对列表组成的 )

{
    "tweet":            "Elasticsearch is very flexible",
    "user": {
        "id":           "@johnsmith",
        "gender":       "male",
        "age":          26,
        "name": {
            "full":     "John Smith",
            "first":    "John",
            "last":     "Smith"
        }
    }
}
# 实际存储的结构
{
    "tweet":            [elasticsearch, flexible, very],
    "user.id":          [@johnsmith],
    "user.gender":      [male],
    "user.age":         [26],
    "user.name.full":   [john, smith],
    "user.name.first":  [john],
    "user.name.last":   [smith]
}

但是这种如果是对象数组的情况,数据相关性就会丢失了,如下如果使用默认的映射规则,"comments"会被映射为object,这样的结构就没办法区分,所以ES提供了nested字段类型,作为嵌套对象数组类型的区分,即会为每一个对象都对应一个独立的文档

{
  "title": "Nest eggs",
  "body":  "Making your money work...",
  "tags":  [ "cash", "shares" ],
  "comments": [ 
    {
      "name":    "John Smith",
      "comment": "Great article",
      "age":     28,
      "stars":   4,
      "date":    "2014-09-01"
    },
    {
      "name":    "Alice White",
      "comment": "More like this please",
      "age":     31,
      "stars":   5,
      "date":    "2014-10-22"
    }
  ]
}
#默认以object类型映射
{
  "title":            [ eggs, nest ],
  "body":             [ making, money, work, your ],
  "tags":             [ cash, shares ],
  "comments.name":    [ alice, john, smith, white ],
  "comments.comment": [ article, great, like, more, please, this ],
  "comments.age":     [ 28, 31 ],
  "comments.stars":   [ 4, 5 ],
  "comments.date":    [ 2014-09-01, 2014-10-22 ]
}
#以nested类型映射
{ 
  "comments.name":    [ john, smith ],
  "comments.comment": [ article, great ],
  "comments.age":     [ 28 ],
  "comments.stars":   [ 4 ],
  "comments.date":    [ 2014-09-01 ]
}
{ 
  "comments.name":    [ alice, white ],
  "comments.comment": [ like, more, please, this ],
  "comments.age":     [ 31 ],
  "comments.stars":   [ 5 ],
  "comments.date":    [ 2014-10-22 ]
}
{ 
  "title":            [ eggs, nest ],
  "body":             [ making, money, work, your ],
  "tags":             [ cash, shares ]
}

参考

https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.5.4.zip

https://www.elastic.co/guide/cn/elasticsearch/guide/current/combining-filters.html

https://www.cnblogs.com/Transkai/p/11051869.html
https://www.elastic.co/guide/cn/elasticsearch/guide/cn/getting-started.html

https://es.xiaoleilu.com/030_Data/30_Create.html

https://www.cnblogs.com/gangle/p/9328257.html
http://localhost:9200/

java api聚合操作
https://blog.csdn.net/fly910905/article/details/81487269
https://blog.csdn.net/comeonyangzi/article/details/80597974
https://blog.csdn.net/majun_guang/article/details/81103623

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值