Test Elasticsearch

package com.itheima.elasticsearch.test;

import java.awt.MultipleGradientPaint;
import java.io.IOException;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Before;
import org.junit.Test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.elasticsearch.domain.Article;

public class TestElasticsearch {

private Client client;


/**获取Transport Client
 * @throws Exception */
@Before
public void getClient() throws Exception{
	// ElasticSearch 服务默认端口 9300
	client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(
			InetAddress.getByName("127.0.0.1"),9300));
}

/**使用json,创建文档,自动创建索引,自动创建映射*/
@Test
public void createDocument_1(){
	//json的数据格式
	String source = "{" +
	"\"id\":\"1\","+
	"\"title\":\"ElasticSearch是一个基于Lucene的搜索服务器\"," +
	"\"content\":\"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口\"" +
	"}";
	/**创建文档,定义索引名称,文档类型,主键唯一标识ID*/
	// execute().actionGet()执行   == get()执行;
	IndexResponse indexResponse = client.prepareIndex("blog", "article", "1").setSource(source).get();
	// 获取响应的信息
	System.out.println("索引名称:"+indexResponse.getIndex());
	System.out.println("文档类型:"+indexResponse.getType());
	System.out.println("ID:"+indexResponse.getId());
	System.out.println("版本:"+indexResponse.getVersion());
	System.out.println("是否创建成功:"+indexResponse.isCreated());
	client.close();
}

/**使用map,创建文档,自动创建索引,自动创建映射*/
@Test
public void createDocument_2(){
	//json的数据格式
	Map source = new HashMap();
	source.put("id", "2");
	source.put("title", "Lucene的搜索服务器");
	source.put("content", "基于RESTful web接口");
	/**创建文档,定义索引名称,文档类型,主键唯一标识ID*/
	// execute().actionGet()执行   == get()执行;
	IndexResponse indexResponse = client.prepareIndex("blog", "article", "2").setSource(source).get();
	// 获取响应的信息
	System.out.println("索引名称:"+indexResponse.getIndex());
	System.out.println("文档类型:"+indexResponse.getType());
	System.out.println("ID:"+indexResponse.getId());
	System.out.println("版本:"+indexResponse.getVersion());
	System.out.println("是否创建成功:"+indexResponse.isCreated());
	client.close();
}

/**使用es的帮助类,创建文档,自动创建索引,自动创建映射
 * @throws Exception */
@Test
public void createDocument_3() throws Exception{
	XContentBuilder source = XContentFactory.jsonBuilder()
			.startObject()
				.field("id", "3")
				.field("title","ElasticSearch是一个基于Lucene的搜索服务器")
				.field("content","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口")
			.endObject();
	System.out.println(source.toString());
	/**创建文档,定义索引名称,文档类型,主键唯一标识ID*/
	// execute().actionGet()执行   == get()执行;
	IndexResponse indexResponse = client.prepareIndex("blog", "article", "3").setSource(source).get();
	// 获取响应的信息
	System.out.println("索引名称:"+indexResponse.getIndex());
	System.out.println("文档类型:"+indexResponse.getType());
	System.out.println("ID:"+indexResponse.getId());
	System.out.println("版本:"+indexResponse.getVersion());
	System.out.println("是否创建成功:"+indexResponse.isCreated());
	client.close();
}

/***
 * 6.2.搜索文档数据(单个索引)
 */
@Test
public void testGetData_1() throws Exception{
	GetResponse getResponse = client.prepareGet("blog", "article", "1")
						.get();
	System.out.println(getResponse.getSourceAsString());
	//关闭
	client.close();
}

/**
 * 6.3.搜索文档数据(多个索引)
 */
@Test
public void testGetData_2() throws Exception{
	MultiGetResponse multiGetResponse = client.prepareMultiGet()
			.add("blog", "article", "1")
			.add("blog","article","2","3")
			.get();
	// 遍历获取值
	for(MultiGetItemResponse itemResponse:multiGetResponse){
		GetResponse response = itemResponse.getResponse();
		// 存在数据
		if(response.isExists()){
			String sourceAsString = response.getSourceAsString();
			System.out.println(sourceAsString);
		}
	}
	//关闭
	client.close();
}

/**
 * 6.4.更新文档数据
 */
@Test
public void testUpdate_1() throws Exception{
	UpdateRequest request = new UpdateRequest();
	request.index("blog");// 搜索名称
	request.type("article"); // 文档类型
	request.id("1"); // 更新的id
	request.doc(XContentFactory.jsonBuilder().startObject()
			.field("id","1")
			.field("title", "更新:基于Lucene的搜索服务器")
			.field("content","更新:分布式多用户能力的全文搜索引擎,基于RESTful web接口")
			.endObject());
	
	UpdateResponse updateResponse = client.update(request).get();
	// 获取响应的信息
	System.out.println("索引名称:"+updateResponse.getIndex());
	System.out.println("文档类型:"+updateResponse.getType());
	System.out.println("ID:"+updateResponse.getId());
	System.out.println("版本:"+updateResponse.getVersion());
	System.out.println("是否创建成功:"+updateResponse.isCreated());
	//关闭
	client.close();
}

/**
 * 6.4.更新文档数据
 */
@Test
public void testUpdate_2() throws Exception{
	
	UpdateResponse updateResponse = client.update(new UpdateRequest("blog", "article", "2")
			.doc(XContentFactory.jsonBuilder().startObject()
			.field("id","2")
			.field("title", "更新2:基于Lucene的搜索服务器")
			.field("content","更新2:分布式多用户能力的全文搜索引擎,基于RESTful web接口")
			.endObject())).get();
	// 获取响应的信息
	System.out.println("索引名称:"+updateResponse.getIndex());
	System.out.println("文档类型:"+updateResponse.getType());
	System.out.println("ID:"+updateResponse.getId());
	System.out.println("版本:"+updateResponse.getVersion());
	System.out.println("是否创建成功:"+updateResponse.isCreated());
	//关闭
	client.close();
}

/**
 * 6.4.更新文档数据
 */
@Test
public void testUpdate_3_upsert() throws Exception{
	// 设置一个查询的条件,使用ID查询,如果查找不到数据,添加IndexRequest中的文档数据
	IndexRequest indexRequest = new IndexRequest("blog", "article", "4")
			.source(XContentFactory.jsonBuilder().startObject()
			.field("id","4")
			.field("title", "基于Lucene的搜索服务器")
			.field("content","分布式多用户能力的全文搜索引擎,基于RESTful web接口")
			.endObject());
	
	// 设置更新的数据,使用ID查询,如果查找到数据,更新UpdateRequest中的文档数据
	UpdateRequest updateRequest = new UpdateRequest("blog", "article", "4")
			.doc(XContentFactory.jsonBuilder().startObject()
			.field("title", "elasticsearch是对lucene进行了封装")
			.endObject()).upsert(indexRequest);
	
	UpdateResponse updateResponse = client.update(updateRequest).get();
	// 获取响应的信息
	System.out.println("索引名称:"+updateResponse.getIndex());
	System.out.println("文档类型:"+updateResponse.getType());
	System.out.println("ID:"+updateResponse.getId());
	System.out.println("版本:"+updateResponse.getVersion());
	System.out.println("是否创建成功:"+updateResponse.isCreated());
	//关闭
	client.close();
}

/**
 * 6.5.删除文档数据
 */
@Test
public void testDelete() throws Exception{
	
	
	DeleteResponse deleteResponse = client.prepareDelete("blog", "article", "3").execute().actionGet();
	// 获取响应的信息
	System.out.println("索引名称:"+deleteResponse.getIndex());
	System.out.println("文档类型:"+deleteResponse.getType());
	System.out.println("ID:"+deleteResponse.getId());
	System.out.println("版本:"+deleteResponse.getVersion());
	System.out.println("是否可以查询到:"+deleteResponse.isFound());
	//关闭
	client.close();
}

/**
 * SearchResponse获取,支持各种查询:
 */
@Test
public void testSearch() throws Exception{
	/**
	 * elasticsearch提供 QueryBuilders.queryStringQuery("搜索内容")
	 * 针对多字段的query_string查询
	 * 在title字段,或者content字段去进行条件搜索
	 */

// SearchResponse searchResponse = client.prepareSearch(“blog”)
// .setTypes(“article”)
// .setQuery(QueryBuilders.queryStringQuery(“全面”))
// .get();
/**
* 词条查询是Elasticsearch中的一个简单查询。它仅匹配在给定字段中含有该词条的文档,而且是确切的、未经分析的词条
* elasticsearch提供QueryBuilders.termQuery(“content”, “全文”)
* 对一个字段完成查询
* 在content字段上是否有全文的词条呢?
* * 没有查询到“全文”的结果
* * 查询到“全”的数据结果
/
SearchResponse searchResponse = client.prepareSearch(“blog”)
.setTypes(“article”)
.setQuery(QueryBuilders.termQuery(“content”, “全文”))
.get();
/
*
* 通配符查询允许我们在查询值中使用*和?等通配
* elasticsearch提供QueryBuilders.wildcardQuery(“content”, "全文?")
* 对一个字段完成查询
* 在content字段上是否有
全文?的词条呢? * 表示多个字符(任意的字符串) ?表示单个字符(例如:我们学习的Lucene全文检)
* * 没有查询到“*全文?”的结果
* * 查询到“*全”的数据结果
/
// SearchResponse searchResponse = client.prepareSearch(“blog”)
// .setTypes(“article”)
// .setQuery(QueryBuilders.wildcardQuery(“content”, "全"))
// .get();
/

* fuzzy查询是模糊查询中的第三种类型,它基于编辑距离算法来匹配文档。编辑距离的计算
基于我们提供的查询词条和被搜索文档。此查询很占用CPU资源,但当需要模糊匹配时它很有用,
例如,当用户拼写错误时,也是可以查询到我们想要的结果
索引库中title存放的是lucene,那么在搜索的时候使用lucena也可以搜索到结果
*/
// SearchResponse searchResponse = client.prepareSearch(“blog”)
// .setTypes(“article”)
// .setQuery(QueryBuilders.fuzzyQuery(“title”, “lucena”))
// .get();

	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	System.out.println("查询的结果数量有"+hits.getTotalHits()+"条");
	// 遍历每条数据
	Iterator iterator = hits.iterator();
	while(iterator.hasNext()){
		SearchHit searchHit = iterator.next();
		System.out.println("所有的数据JSON的数据格式:"+searchHit.getSourceAsString());
		// 获取每个字段的数据
		System.out.println("id:"+searchHit.getSource().get("id"));
		System.out.println("title:"+searchHit.getSource().get("title"));
		System.out.println("content:"+searchHit.getSource().get("content"));
		System.out.println("**********************************************");
		for(Iterator ite = searchHit.iterator();ite.hasNext();){
			SearchHitField next = ite.next();
			System.out.println(next.getValues());
		}
	}
	//关闭
	client.close();
}

/**
 * 10.1.索引相关操作 (IK分词)
 * * 创建索引
 * * 删除索引
 */
@Test
public void testCreateIndex() throws Exception{
	// 创建索引
	client.admin().indices().prepareCreate("blog").get();
	
	// 删除索引
	// client.admin().indices().prepareDelete("blog2").get();
	//关闭
	client.close();
}

/**
 * 创建映射
 */
@Test
public void testCreateIndexMapping() throws Exception{
	//构建json的数据格式,创建映射
	/**
	 * "mappings" : {
			"article" : 
			{
				"dynamic" : "false",
				"properties" : 
				{
					"id" : { "type" : "integer" ,"store":"yes"},
					"title" : { "type" : "string" ,"store":"yes","analyzer","ik"},
					"content" : { "type" : "string" ,"store":"yes","analyzer","ik"}
				}
			}
		}
	 */
	XContentBuilder mappingBuilder = XContentFactory.jsonBuilder()
			.startObject()
				.startObject("article")
					.startObject("properties")
						.startObject("id")
							.field("type","integer").field("store", "yes")
						.endObject()
						.startObject("title")
							.field("type","string").field("store", "yes").field("analyzer","ik")
						.endObject()
						.startObject("content")
							.field("type","string").field("store", "yes").field("analyzer","ik")
						.endObject()
					.endObject()
				.endObject()
			.endObject();
	PutMappingRequest request = Requests.putMappingRequest("blog")
			.type("article")
			.source(mappingBuilder);
	client.admin().indices().putMapping(request).get();
	//关闭
	client.close();
}

/**使用es的帮助类,创建文档
 * @throws Exception */
@Test
public void createDocumentMapping() throws Exception{
	XContentBuilder source = XContentFactory.jsonBuilder()
			.startObject()
				.field("id", 1)
				.field("title","ElasticSearch是一个基于Lucene的搜索服务器")
				.field("content","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便")
			.endObject();
	/**创建文档,定义索引名称,文档类型,主键唯一标识ID*/
	// execute().actionGet()执行   == get()执行;
	IndexResponse indexResponse = client.prepareIndex("blog", "article", "1").setSource(source).get();
	// 获取响应的信息
	System.out.println("索引名称:"+indexResponse.getIndex());
	System.out.println("文档类型:"+indexResponse.getType());
	System.out.println("ID:"+indexResponse.getId());
	System.out.println("版本:"+indexResponse.getVersion());
	System.out.println("是否创建成功:"+indexResponse.isCreated());
	client.close();
}

/**使用Jackson(处理对象和json数据之间的转换),创建文档
 * @throws Exception */
@Test
public void createDocumentJacksonMapping() throws Exception{
	
	Article article = new Article();
	article.setId(2);
	article.setTitle("2在传智播客学习使用Jackson对象将Article转换成json,ElasticSearch是一个基于Lucene的搜索服务器");
	article.setContent("2它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便");
	
	ObjectMapper objectMapper = new ObjectMapper();
	String source = objectMapper.writeValueAsString(article);
	System.out.println("source:"+source);
	
	IndexResponse indexResponse = client.prepareIndex("blog", "article", article.getId().toString()).setSource(source).get();
	// 获取响应的信息
	System.out.println("索引名称:"+indexResponse.getIndex());
	System.out.println("文档类型:"+indexResponse.getType());
	System.out.println("ID:"+indexResponse.getId());
	System.out.println("版本:"+indexResponse.getVersion());
	System.out.println("是否创建成功:"+indexResponse.isCreated());
	client.close();
}

/**使用Jackson(处理对象和json数据之间的转换),修改文档
 * @throws Exception */
@Test
public void updateDocumentJacksonMapping() throws Exception{
	
	Article article = new Article();
	article.setId(1);
	article.setTitle("传智播客学习使用Jackson对象,ElasticSearch是一个基于Lucene的搜索服务器");
	article.setContent("它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便");
	
	ObjectMapper objectMapper = new ObjectMapper();
	/**方案一*/

// UpdateResponse updateResponse = client.prepareUpdate(“blog”, “article”, article.getId().toString())
// .setDoc(objectMapper.writeValueAsString(article)).get();
/*方案二/
UpdateResponse updateResponse = client.update(
new UpdateRequest(“blog”, “article”, article.getId().toString())
.doc(objectMapper.writeValueAsString(article))).get();
// 获取响应的信息
System.out.println(“索引名称:”+updateResponse.getIndex());
System.out.println(“文档类型:”+updateResponse.getType());
System.out.println(“ID:”+updateResponse.getId());
System.out.println(“版本:”+updateResponse.getVersion());
System.out.println(“是否创建成功:”+updateResponse.isCreated());
// 关闭
client.close();
}

/**删除文档
 * @throws Exception */
@Test
public void deleteDocument() throws Exception{
	
	/**方案一*/

// DeleteResponse deleteResponse = client.prepareDelete(“blog”, “article”, “1”).get();
/*方案二/
DeleteResponse deleteResponse = client.delete(new DeleteRequest(“blog”, “article”, “4”)).get();
// 获取响应的信息
System.out.println(“索引名称:”+deleteResponse.getIndex());
System.out.println(“文档类型:”+deleteResponse.getType());
System.out.println(“ID:”+deleteResponse.getId());
System.out.println(“版本:”+deleteResponse.getVersion());
System.out.println(“是否删除成功:”+deleteResponse.isFound());
// 关闭
client.close();
}

/**
 * SearchResponse获取,支持各种查询:IK分词器后的查询
 */
@Test
public void testSearchMapping() throws Exception{
	/**
	 * elasticsearch提供 QueryBuilders.queryStringQuery("搜索内容")
	 * 针对多字段的query_string查询
	 * 在title字段,或者content字段去进行条件搜索
	 */

// SearchResponse searchResponse = client.prepareSearch(“blog”)
// .setTypes(“article”)
// .setQuery(QueryBuilders.queryStringQuery(“全面”))
// .get();
/**
* 词条查询是Elasticsearch中的一个简单查询。它仅匹配在给定字段中含有该词条的文档,而且是确切的、未经分析的词条
* elasticsearch提供QueryBuilders.termQuery(“content”, “全文”)
* 对一个字段完成查询
* 在content字段上是否有全文的词条呢?
* * 没有查询到“全文”的结果
* * 查询到“全”的数据结果
/
SearchResponse searchResponse = client.prepareSearch(“blog”)
.setTypes(“article”)
.setQuery(QueryBuilders.termQuery(“title”, “传智播客”))
.get();
/
*
* 通配符查询允许我们在查询值中使用*和?等通配
* elasticsearch提供QueryBuilders.wildcardQuery(“content”, "全文?")
* 对一个字段完成查询
* 在content字段上是否有
全文?的词条呢? * 表示多个字符(任意的字符串) ?表示单个字符(例如:我们学习的Lucene全文检)
* * 没有查询到“*全文?”的结果
* * 查询到“*全”的数据结果
/
// SearchResponse searchResponse = client.prepareSearch(“blog”)
// .setTypes(“article”)
// .setQuery(QueryBuilders.wildcardQuery(“content”, "全?"))
// .get();
/

* fuzzy查询是模糊查询中的第三种类型,它基于编辑距离算法来匹配文档。编辑距离的计算
基于我们提供的查询词条和被搜索文档。此查询很占用CPU资源,但当需要模糊匹配时它很有用,
例如,当用户拼写错误时,也是可以查询到我们想要的结果
索引库中title存放的是lucene,那么在搜索的时候使用lucena也可以搜索到结果
*/
// SearchResponse searchResponse = client.prepareSearch(“blog”)
// .setTypes(“article”)
// .setQuery(QueryBuilders.fuzzyQuery(“title”, “lucena”))
// .get();

	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	System.out.println("查询的结果数量有"+hits.getTotalHits()+"条");
	// 遍历每条数据
	Iterator iterator = hits.iterator();
	while(iterator.hasNext()){
		SearchHit searchHit = iterator.next();
		System.out.println("所有的数据JSON的数据格式:"+searchHit.getSourceAsString());
		// 获取每个字段的数据
		System.out.println("id:"+searchHit.getSource().get("id"));
		System.out.println("title:"+searchHit.getSource().get("title"));
		System.out.println("content:"+searchHit.getSource().get("content"));
		System.out.println("**********************************************");
		for(Iterator ite = searchHit.iterator();ite.hasNext();){
			SearchHitField next = ite.next();
			System.out.println(next.getValues());
		}
	}
	//关闭
	client.close();
}

/**
 * 10.5.各种查询
 * 查询所有
 * */

@Test
public void testQueryAll() throws Exception{
	
	/**
	 * 查询所有
	 * QueryBuilders.matchAllQuery()
	 * */
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			.setQuery(QueryBuilders.matchAllQuery())
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**
 * 解析查询字符串
 * */
@Test
public void testQueryString() throws Exception{
	/**
	 * 可以针对多个字段查询:QueryBuilders.queryStringQuery("传智播客")
	 * 针对某个字段:QueryBuilders.queryStringQuery("传智播客").field("content")
	 * */
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			.setQuery(QueryBuilders.queryStringQuery("传智播客").field("content").field("title"))
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**
 * 通配符查询
 * */
@Test
public void testWildcardQuery() throws Exception{
	/**
	 * 
	 * */
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			.setQuery(QueryBuilders.wildcardQuery("title", "传智播?"))
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**
 * 词条查询
 * termQuery("key", obj) 完全匹配
   termsQuery("key", obj1, obj2..)   一次匹配多个值,只有有一个值是正确的,就可以查询出数据
 * */
@Test
public void testTermQuery() throws Exception{
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			// .setQuery(QueryBuilders.termQuery("title", "传智播客"))
			.setQuery(QueryBuilders.termsQuery("title", "中科软","搜索"))
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**
 * 字段匹配查询
 * matchQuery("key", Obj) 单个匹配, field不支持通配符, 前缀具高级特性
 * multiMatchQuery("text", "field1", "field2"..);  匹配多个字段, field有通配符忒行
 */
@Test
public void testMatchQuery() throws Exception{
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			//.setQuery(QueryBuilders.matchQuery("title", "传播").analyzer("ik").fuzziness(0.1))
			//.setQuery(QueryBuilders.matchPhraseQuery("title", "传 播").slop(1))
			//.setQuery(QueryBuilders.matchPhrasePrefixQuery("title", "传 ").slop(1).maxExpansions(20))
			
			// 多字段完成搜索
			.setQuery(QueryBuilders.multiMatchQuery("搜索", "title","content"))
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**ID查询(标识符查询)*/
@Test
public void testIds() throws Exception{
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			.setQuery(QueryBuilders.idsQuery().ids("1","2"))
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**
 * 相似度查询(模糊查询)
 * 即使犯了一个拼写错误,Elasticsearch仍然设法找到我们感兴趣的文档。
 * */
@Test
public void testFuzzyQuery() throws Exception{
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			.setQuery(QueryBuilders.fuzzyQuery("content", "Elasticsearc"))
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**
 * 范围查询
 * includeLower(true):范围中包含上界
 * includeUpper(true):范围中包含下界
 * */
@Test
public void testRange() throws Exception{
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			//.setQuery(QueryBuilders.rangeQuery("id").gte(1).lte(2))
			// .setQuery(QueryBuilders.rangeQuery("id").from(1).to(2))
			.setQuery(QueryBuilders.rangeQuery("content").from("当前流行").to("搜索引擎").includeLower(true).includeUpper(true))
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**
 * 跨度查询
	下面代码表示,从首字母开始,查询content字段=稳定的数据,稳定从前往后数,前面的词为300个,可以测试30看是否能查询出数据(没有数据)。
 */
@Test
public void testSpan() throws Exception{
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			.setQuery(QueryBuilders.spanFirstQuery(QueryBuilders.spanTermQuery("content", "稳定"),30))
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**
 * 布尔查询
 * 用来连接多个字段的查询条件
 *       must(QueryBuilders) : AND
	     mustNot(QueryBuilders): NOT
	     should(QueryBuilders):OR 
 * */
@Test
public void testBool() throws Exception{
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			.setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("title", "传智播客"))
					.must(QueryBuilders.rangeQuery("id").from(1).to(2)))
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**排序查询*/
@Test
public void testBoolSort() throws Exception{
	SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
			.setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("title", "传智播客"))
					.must(QueryBuilders.rangeQuery("id").from(1).to(2)))
			.addSort("id", SortOrder.DESC)
			.get();
	SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
	// 显示数据
	this.searchValue(hits);
	//关闭
	client.close();
}

/**
 * 10.6.查询文档分页操作 
		1、 批量向数据表 插入100条记录 。
 */
@Test
public void createDocument100() throws Exception{
	
	ObjectMapper objectMapper = new ObjectMapper();
	for(int i=1;i<=100;i++){
		Article article = new Article();
		article.setId(i);
		article.setTitle(i+"在传智播客学习使用Jackson对象将Article转换成json,ElasticSearch是一个基于Lucene的搜索服务器");
		article.setContent(i+"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便");
		
		String source = objectMapper.writeValueAsString(article);
		IndexResponse indexResponse = client.prepareIndex("blog", "article", article.getId().toString()).setSource(source).get();
	}
	client.close();
}

/**
 * 2、分页查询 
	    查询所有的方法
		searchRequestBuilder 的 setFrom【从0开始】 和 setSize【查询多少条记录】方法实现
 * elasticsearch如果不指定分页,默认是1页显示10条
 */
@Test
public void testPage() throws Exception{
	
	SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog").setTypes("article")
					.setQuery(QueryBuilders.matchAllQuery());// 查询所有
	// 从第一条开始检索,第一页显示20条数据

// searchRequestBuilder.setFrom(0).setSize(20);
searchRequestBuilder.setFrom(20).setSize(20);
searchRequestBuilder.addSort(“id”,SortOrder.DESC);//降序排列
SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();// 等同于get()
SearchHits searchHits = searchResponse.getHits();
//显示数据
this.searchValue(searchHits);
// 关闭
client.close();
}

/**
 * 文字高亮
 * 将返回的文本添加搜索
 * */
@Test
public void testHighLinghter() throws Exception{
	
	ObjectMapper objectMapper = new ObjectMapper();
	
	SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog").setTypes("article");
					//.setQuery(QueryBuilders.termQuery("content", "搜索"));// 词条查询,查询content字段为搜索
	
	// 设置查询条件
	QueryStringQueryBuilder queryStringBuilder = QueryBuilders.queryStringQuery("传智播客");//按照搜索完成,同时在title字段和content字段都完成高亮
	// 表示“搜索”词在title字段和content字段上进行高亮
	queryStringBuilder.field("title").field("content");
	// 表示对title字段进行高亮,高亮后的结果在title字段上体现
	searchRequestBuilder.addHighlightedField("title");
	// 表示对content字段进行高亮,高亮后的结果在content字段上体现
	searchRequestBuilder.addHighlightedField("content");
	// 添加前缀
	searchRequestBuilder.setHighlighterPreTags("");
	// 添加后缀
	searchRequestBuilder.setHighlighterPostTags("");
	// 设置摘要,数据显示的时候,只显示高亮次数多的区域
	int size = 20;
	searchRequestBuilder.setHighlighterFragmentSize(size);
	
	searchRequestBuilder.setQuery(QueryBuilders.boolQuery().must(queryStringBuilder));
	
	SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();// 等同于get()
	SearchHits hits = searchResponse.getHits();
	
	//显示数据
	System.out.println("查询的结果数量有"+hits.getTotalHits()+"条");
	// 遍历每条数据
	Iterator iterator = hits.iterator();
	while(iterator.hasNext()){
		SearchHit searchHit = iterator.next();
		//System.out.println("所有的数据JSON的数据格式:"+searchHit.getSourceAsString());
		
		// 将高亮的处理后的内容返回,将返回的内容放置到原有的数据结果中
		Map highlightFields = searchHit.getHighlightFields();

// System.out.println(highlightFields);
// 如果有高亮的结果,就返回对应的值,如果没有高亮的结果,返回null
HighlightField contentHighlightField = highlightFields.get(“content”);
HighlightField titleHighlightField = highlightFields.get(“title”);

		// 将json的形式转换成对象
		Article article = objectMapper.readValue(searchHit.getSourceAsString(), Article.class);
		
		// 如果highlightField不等于null,表示存在高亮的结果
		String content = "";
		if(contentHighlightField!=null){
			Text[] fragments = contentHighlightField.fragments();
			// 用来读取高亮的结果
			for(Text text:fragments){
				content += text;
			}
			// 将高亮后的结果放置到Article的对象中
			if(content!=null && !"".equals(content)){
				article.setContent(content);
			}
		}
		else{
			if(article.getContent().length()>size){
				article.setContent(article.getContent().substring(0, size));
			}
		}
		// 如果highlightField不等于null,表示存在高亮的结果
		String title = "";
		if(titleHighlightField!=null){
			Text[] fragments = titleHighlightField.fragments();
			// 用来读取高亮的结果
			for(Text text:fragments){
				title += text;
			}
			// 将高亮后的结果放置到Article的对象中
			if(title!=null && !"".equals(title)){
				article.setTitle(title);
			}
		}
		else{
			if(article.getTitle().length()>size){
				article.setTitle(article.getTitle().substring(0, size));
			}
		}
		System.out.println(article);
	}
	// 关闭
	client.close();
}




// 显示查询的结果数据
private void searchValue(SearchHits hits) {
	System.out.println("查询的结果数量有"+hits.getTotalHits()+"条");
	// 遍历每条数据
	Iterator iterator = hits.iterator();
	while(iterator.hasNext()){
		SearchHit searchHit = iterator.next();
		System.out.println("所有的数据JSON的数据格式:"+searchHit.getSourceAsString());
		// 获取每个字段的数据
		System.out.println("id:"+searchHit.getSource().get("id"));
		System.out.println("title:"+searchHit.getSource().get("title"));
		System.out.println("content:"+searchHit.getSource().get("content"));
		System.out.println("**********************************************");
		for(Iterator ite = searchHit.iterator();ite.hasNext();){
			SearchHitField next = ite.next();
			System.out.println(next.getValues());
		}
	}
}

}

你可能感兴趣的:(code)