package xxx.xxx.xxx.xxx;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
/**
* ElasticSearch高级查询基本操作
*
* 操作的入口TransportClient
*/
public class ElasticSearchQuery {
private TransportClient tc;
private int port = 9300;
private String clusterName = "bigdata";
private String node_1 = "hadoop01";
private String node_2 = "hadoop02";
private String node_3 = "hadoop03";
private String[] indices = {"bigdata","bank"};
@Before
public void setUp() throws UnknownHostException {
Settings setting = Settings.builder()
.put("cluster.name",clusterName)
.put("analyzer","ik")
.build();
tc = TransportClient.builder().settings(setting).build();
TransportAddress hadoop = new InetSocketTransportAddress(InetAddress.getByName(node_1),port);
TransportAddress spark = new InetSocketTransportAddress(InetAddress.getByName(node_2),port);
TransportAddress storm = new InetSocketTransportAddress(InetAddress.getByName(node_3),port);
tc.addTransportAddresses(hadoop,spark,storm);
}
/**
* 查找包涵Apache的数据信息
*/
@Test
public void testSearch(){
// tc.prepareSearch(indices)
// .setSearchType(SearchType.DEFAULT)
// .setQuery(QueryBuilders.matchQuery("author", "Apache"))
// .get();
SearchResponse response = tc.prepareSearch(indices)//设置要进行查询的方式,有4中查询方式:QUERY_AND_FETCH、QUERY_THEN_FETCH、DFS_QUERY_AND_FETCH、DFS_QUERY_THEN_FETCH
.setSearchType(SearchType.DEFAULT)//设置查询的内容,和在哪些字段中进行查询,要通过QueryBuilders来进行设置
.setQuery(QueryBuilders.matchQuery("author", "Apache"))
.get();
SearchHits hits = response.getHits();
long totalHits = hits.getTotalHits();
System.out.println("老王为您找到相关结果约 " + totalHits);
for(SearchHit searchHit:hits){
printSearchHit(searchHit);
}
}
@Test
public void testSearch_02(){
SearchResponse searchResponse = tc.prepareSearch(indices)
.setSearchType(SearchType.DEFAULT)
.setQuery(QueryBuilders.prefixQuery("name", "h"))
.addSort("name", SortOrder.DESC)
.setFrom(0)
.setSize(10)
.get();
SearchHits hits = searchResponse.getHits();
long totalHits = hits.getTotalHits();
System.out.println("老王为您找到相关结果约 " + totalHits);
for(SearchHit searchHit: hits){
printSearchHit(searchHit);
}
}
/**
* 查询年龄在35到40之间的成员信息
*/
@Test
public void testSearch_03(){
SearchResponse searchResponse = tc.prepareSearch(indices)
.setSearchType(SearchType.DEFAULT)
.setQuery(QueryBuilders.rangeQuery("age").gte(35).lte(40))
.addSort("balance", SortOrder.DESC)
.setFrom(0)
.setSize(2)
.get();
SearchHits hits = searchResponse.getHits();
long totalHits = hits.getTotalHits();
System.out.println("老王为您找到相关结果约 " + totalHits);
for(SearchHit searchHit:hits){
printSearchHit(searchHit);
}
}
/**
* 执行聚合操作
* 查询年龄在35到40之间的平均年龄
*/
@Test
public void testSearch_04(){
SearchResponse searchResponse = tc.prepareSearch(indices)
.setSearchType(SearchType.DEFAULT)
.setQuery(QueryBuilders.rangeQuery("age").gte(35).lte(40))
.addAggregation(AggregationBuilders.avg("avg_age").field("age"))
.get();
SearchHits hits = searchResponse.getHits();
long totalHits = hits.getTotalHits();
System.out.println("老王为您找到相关结果约 " + totalHits);
Aggregations aggregations = searchResponse.getAggregations();
Map<String, Aggregation> aggregationMap = aggregations.asMap();
for(Map.Entry<String, Aggregation> map:aggregationMap.entrySet()){
String key = map.getKey();
//由Aggregations---->强转为InternalAvg,才拿到平均值
InternalAvg aggregation = (InternalAvg)map.getValue();
System.out.println("key = " + key);
System.out.println("aggregation = " + aggregation.getValue());
}
}
/**
* 代码的高亮显示
* HighLight
* <font color='red'>keyword</font>
* 对于这种高亮显示,就是在查询关键字之前和之后分别追加前缀和后缀
* 前缀:pre
* 后缀:post
*
* 设置高亮注意的地方:
* 1、设置高亮字段:addHighlightedField
* 2、设置高亮的前缀和后缀:
* setHighlighterPreTags("<font color='red'>")
* setHighlighterPostTags("</font>")
* 3、获取高亮数据
* searchHit.getHighlightFields()中的fragment获取
*/
@Test
public void testSearch_05(){
SearchResponse response = tc.prepareSearch(indices)
.setSearchType(SearchType.DEFAULT)
.setQuery(QueryBuilders.matchQuery("name", "hadoop02"))
.addHighlightedField("name")
.setHighlighterPreTags("<font color='red'>")
.setHighlighterPostTags("</font>")
.get();
SearchHits searchHits = response.getHits();
long totalHits = searchHits.getTotalHits();
System.out.println("老王为您找到相关结果约 " + totalHits);
for(SearchHit searchHit : searchHits){
System.out.println(" ================== " );
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
for(Map.Entry<String, HighlightField> me : highlightFields.entrySet()){
String key = me.getKey();
System.out.println("key = " + key);
HighlightField highlightField = me.getValue();
String name = highlightField.getName();
System.out.println("name = " + name);
Text[] fragments = highlightField.getFragments();
String hightStr = "";
for(Text text : fragments){
hightStr += text.toString();
}
System.out.println("hightStr = " + hightStr);
}
}
}
/**
* 查询中文
*
* 分词:
* 我们发现设置Query为termQuery,QueryBuilders.termQuery("author", "孙")有结果
* 而Query为termQuery,QueryBuilders.termQuery("author", "孙鹏")没有结果
* 这是因为中文分词的原因,英文分词非常简单:就是通过一个个的空格进行拆分,而汉字的拆分默认情况下就是一个字一个字的拆
*
* 我们要想查询孙鹏 或者鹏飞这些词组的时候,默认的拆分方式就提供不了数据了,为了满足用户的需要,在软件发展过程中就有非常多的
* 各种各样的分词法(庖丁解牛分词法,IK分词法)
*
* 如果使用了IK等分词法,对索引库中已经存在的数据不执行相应的分词,只有对新增的数据才会执行相应的分词!!!
*/
@Test
public void testSearch_Chinese(){
indices = new String[]{"bigdata"};
SearchResponse response = tc.prepareSearch(indices)
.setSearchType(SearchType.DEFAULT) //奥利猫(ik之前) 法拉狗
.setQuery(QueryBuilders.termQuery("author", "奥利"))
.get();
SearchHits hits = response.getHits();
long totalHits = hits.getTotalHits();
System.out.println("老王为您找到相关结果约 " + totalHits);
for(SearchHit searchHit : hits){
printSearchHit(searchHit);
}
}
private void printSearchHit(SearchHit searchHit){
String index = searchHit.getIndex();
String type = searchHit.getType();
String id = searchHit.getId();
long version = searchHit.getVersion();
float score = searchHit.getScore();
Map<String, Object> source = searchHit.getSource();
System.out.println("index "+index);
System.out.println("type "+type);
System.out.println("id "+id);
System.out.println("version "+version);
System.out.println("score "+score);
System.out.println("source "+source);
}
@After
public void cleanUp(){
if(tc != null){
tc.close();
}
}
}
ES高级查询,高亮显示
最新推荐文章于 2024-09-28 19:21:32 发布