elasticsearch作为搜索引擎,用处之一就是快速处理日志查
一、简介
集群(Cluster):所有数据提供存储和检索的集合(服务器集合),根据明细来指定要加入哪个集群,默认“elasticsearch”
结点(Node):提供存储和检索的一台服务器
索引(Index):类似于数据库,是相关文档存储的地方。“建立一个文档”,“索引一个文档”表示把一个文档存储在某个索引中
类型(Type):文档的逻辑分类,类似于数据库的表
文档(Document):一条完整的记录,相当于数据库表中的一条记录
域(Fields):相当于表中的一个column
二、Logstash输出到Elasticsearch
output{
elasticsearch {
hosts => ["192.168.12.122:9200"]
index => "share_app_logs_index_%{+YYYY.MM.dd}"
}
}
action = >"index",是一个文档建立的索引,删除创建等都根据该id进行处理
三、elasticsearch在java中的应用
1. TransportClient是java封装的对象,通过transport模块远程连接到elasticsearch集群,向集群节点发送请求
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>
// on startup
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY) // @1
.addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.1.10"), 9300)) // @2
.addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.1.11"), 9300));
// on shutdown
client.close();
2. Java Rest Client详解
java Low Level REST Client:elasticsearch client 低级别客户端。它允许通过http请求与Elasticsearch集群进行通信。API本身不负责数据的编码解码,由用户去编码解码。它与所有的ElasticSearch版本兼容
Java High Level REST Client:Elasticsearch client官方高级客户端。基于低级客户端,它定义的API,已经对请求与响应数据包进行编码解码
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>6.4.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.4.0</version>
<type>pom</type>
</dependency>
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
// close
client.close();
获取到client后就相当于 redis一样,可以put进去数据 也可以get到对应的数据
保存
Map<String, Object> source = new HashMap<String, Object>();
source.put("code", "11");
source.put("name", "yiyang");
source.put("info", "重组");
source.put("content", "是否可以成功);
source.put("my_title", "我的标题");
source.put("you_title", "你的标题");
source.put("isDelete", true);
client.prepareIndex("index", "my_type").setId("1").setSource(source).get();
查询
GetResponse res = client.prepareGet("index", "my_type", "1").get();
res.getSource().get("content");
检索
QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("yiyang", "name", "content");
SearchResponse res = client.prepareSearch().setIndices("index").setTypes("my_type").setQuery(queryBuilder).get();
res.getHits().getTotalHits(); //获取检索到文本个数
res.getHits().getAt(i).getSource().get("content"));获取其中一个的内容,可以遍历得到
public class QueryBuilderTest extends AbstractJunitTest {
private static final String INDEX2 = "index";
private static final String TYPE2 = "my_type";
public String text = "yiyang";
/**
* 单个精确值查找(termQuery)
*/
@Test
public void termQuery() {
QueryBuilder queryBuilder = QueryBuilders.termQuery("code", "01");
queryBuilder = QueryBuilders.termQuery("isDelete", true);
queryBuilder = QueryBuilders.termQuery("my_title", "我的标题12323abcd");
searchFunction(queryBuilder);
}
/**
* 多个值精确查找(termsQuery)
*
* 一个查询相匹配的多个value
*/
@Test
public void termsQuery() {
QueryBuilder queryBuilder = QueryBuilders.termsQuery("code", "01", "03", "04");
searchFunction(queryBuilder);
}
/**
* 查询相匹配的文档在一个范围(rangeQuery)
*/
@Test
public void rangeQuery() {
QueryBuilder queryBuilder = QueryBuilders
.rangeQuery("code") // 查询code字段
.from("02")
.to("04")
.includeLower(true) // 包括下界
.includeUpper(false);// 不包括上界
searchFunction(queryBuilder);
}
/**
* 查询相匹配的文档在一个范围(prefixQuery)
*/
@Test
public void prefixQuery() {
QueryBuilder queryBuilder = QueryBuilders.prefixQuery("my_title", "我的");
searchFunction(queryBuilder);
}
/**
* 通配符检索(wildcardQuery)
*
* 值使用用通配符,常用于模糊查询
*
* 匹配具有匹配通配符表达式( (not analyzed )的字段的文档。 支持的通配符:
* *,它匹配任何字符序列(包括空字符序列)
* ?,它匹配任何单个字符。
*
* 请注意,此查询可能很慢,因为它需要遍历多个术语。 为了防止非常慢的通配符查询,通配符不能以任何一个通配符*或?开头。
*/
@Test
public void wildcardQuery() {
QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("my_title", "*6789*");
queryBuilder = QueryBuilders.wildcardQuery("my_title", "*345");
queryBuilder = QueryBuilders.wildcardQuery("name", "?闻");
searchFunction(queryBuilder);
}
/**
* 正则表达式检索(regexpQuery) 不需要^、$
*/
@Test
public void regexpQuery() {
QueryBuilder queryBuilder = QueryBuilders.regexpQuery("my_title", "我的.+f");
searchFunction(queryBuilder);
}
/**
* 使用模糊查询匹配文档查询(fuzzyQuery)
*/
@Test
public void fuzzyQuery() {
QueryBuilder queryBuilder = QueryBuilders.fuzzyQuery("name", "科技");
searchFunction(queryBuilder);
}
/**
* 类型检索(typeQuery)
*
* 查询该类型下的所有数据
*/
@Test
public void typeQuery() {
QueryBuilder queryBuilder = QueryBuilders.typeQuery(TYPE2);
searchFunction(queryBuilder);
}
/**
* Ids检索, 返回指定id的全部信息 (idsQuery)
*
* 在idsQuery(type)方法中,也可以指定具体的类型
*/
@Test
public void idsQuery() {
QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1", "4", "10");
searchFunction(queryBuilder);
}
/************************************************************ 全文检索 ************************************************************/
/**
* 单个匹配 (matchQuery)
*
* 感觉跟termQuery效果一样
*/
@Test
public void matchQuery() {
QueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "科技");
searchFunction(queryBuilder);
}
/**
* 查询匹配所有文件 (matchAllQuery)
*/
@Test
public void matchAllQuery() {
QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
searchFunction(queryBuilder);
}
/**
* 匹配多个字段, field可以使用通配符(multiMatchQuery)
*/
@Test
public void multiMatchQuery() {
QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("132445dfgdfg", "my_title", "name", "you_title");
queryBuilder = QueryBuilders.multiMatchQuery("132445dfgdfg", "*title"); //字段使用通配符
searchFunction(queryBuilder);
}
/**
* 字符串检索(queryString)
*
* 一个使用查询解析器解析其内容的查询。
* query_string查询提供了以简明的简写语法执行多匹配查询 multi_match queries ,布尔查询 bool queries ,提升得分 boosting ,模糊
* 匹配 fuzzy matching ,通配符 wildcards ,正则表达式 regexp 和范围查询 range queries 的方式。
*
* 支持参数达10几种
*/
@Test
public void queryString() {
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("*技术"); //通配符查询
// QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("我的.+f");
searchFunction(queryBuilder);
}
/**
* must 相当于and,就是都满足
* should 相当于or,满足一个或多个
* must_not 都不满足
*/
@Test
public void testQueryBuilder2() {
// "科技视频"分词的结果是"科技", "视频", "频"
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
// queryBuilder.must(QueryBuilders.wildcardQuery("name", "*科技*"));
// queryBuilder.must(QueryBuilders.wildcardQuery("info", "*共*"));
// queryBuilder.must(QueryBuilders.wildcardQuery("content", "*美丽*"));
queryBuilder.should(QueryBuilders.wildcardQuery("name", "*科技*"));
queryBuilder.should(QueryBuilders.wildcardQuery("info", "*共*"));
queryBuilder.should(QueryBuilders.wildcardQuery("content", "*美丽*"));
queryBuilder.minimumShouldMatch(2); // 最少匹配数
// queryBuilder.mustNot(QueryBuilders.wildcardQuery("name", "*科技*"));
// queryBuilder.mustNot(QueryBuilders.wildcardQuery("info", "*共*"));
// queryBuilder.mustNot(QueryBuilders.wildcardQuery("content", "*美丽*"));
searchFunction(queryBuilder);
}
/**
* 查询遍历抽取
*
* 查询结果是根据分值排序(从大到小)
*
* @param queryBuilder
*/
private void searchFunction(QueryBuilder queryBuilder) {
SearchRequestBuilder requestBuilder = client.prepareSearch().setIndices(INDEX2).setTypes(TYPE2)
.setScroll(new TimeValue(60000)).setQuery(queryBuilder);
SearchResponse response = requestBuilder.setFrom(0).setSize(100).execute().actionGet();
System.out.println("--------------查询结果:----------------------");
for (SearchHit hit : response.getHits()) {
System.out.println("分值:" + hit.getScore()); // 相关度
Map<String, Object> map = hit.getSource();
for (String sKey : map.keySet()) {
System.out.println(sKey + ": " + map.get(sKey));
}
System.out.println("--------------");
}
System.out.println("-----------------------------------");
}
}