Windows下使用Java调用ElasticSearch提供的相关API进行数据搜索完整实例演示

安装包elasticsearch-rtf下载

elasticsearch中文发行版,针对中文集成了相关插件(包含ik analyzer),并带有Demo,方便新手学习,或者在生产环境中直接使用

redis下载

http://pan.baidu.com/s/1kTD2XG7

官方视频教程 
    http://www.elasticsearch.org/videos/

Window 环境

下载完解开有以下个包 
   bin 是运行的脚本, config 是设置文件, lib 是放依赖的包。 
 Windows下使用Java调用ElasticSearch提供的相关API进行数据搜索完整实例演示

启动解压目录下的 bin 名称的文件夹,双击 elasticsearch.bat 文件,就可以启动 elasticsearch ,启动成功界面如下 :

Windows下使用Java调用ElasticSearch提供的相关API进行数据搜索完整实例演示

启动成功后 , 会在解压目录下增加 2 个文件件 ,data 用于数据存储 , logs 用于日志记录 , 可以自己创建 plugins 目录中用于放置自己的插件。

此时可以在浏览器中输入  http://localhost:9200/

{
    "status": 200,
    "name": "Carlos Lobo",
    "cluster_name": "elasticsearch",
    "version": {
        "number": "1.7.2",
        "build_hash": "e43676b1385b8125d647f593f7202acbd816e8ec",
        "build_timestamp": "2015-09-14T09:49:53Z",
        "build_snapshot": false,
        "lucene_version": "4.10.4"
    },
    "tagline": "You Know, for Search"
}

出现上面结果 , 表示成功启动!

Java 模拟简单搜索

POM文件(我这用的maven工程)

<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<es.version>1.5.2</es.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.elasticsearch</groupId>
			<artifactId>elasticsearch</artifactId>
			<version>${es.version}</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.6.2</version>
		</dependency>
	</dependencies>


实体类

package org.dennisit.entity;

public class Medicine {

	private Integer id;// id
	private String name;// 名称
	private String function;// 功能
	private double price;// 价格

	public Medicine() {
		super();
	}

	public Medicine(Integer id, String name, double price, String function) {
		super();
		this.id = id;
		this.name = name;
		this.price = price;
		this.function = function;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getFunction() {
		return function;
	}

	public void setFunction(String function) {
		this.function = function;
	}
}


模拟数据

package org.dennisit.entity;

import java.util.ArrayList;
import java.util.List;

import org.dennisit.util.JsonUtil;

public class DataFactory {

	public static DataFactory dataFactory = new DataFactory();

	private DataFactory() {
	}

	public DataFactory getInstance() {
		return dataFactory;
	}

	public static List<String> getInitJsonData() {
		List<String> list = new ArrayList<String>();
		String data1 = JsonUtil.obj2JsonData(new Medicine(1, "感冒 胶囊", 25.1, "功能主治:银花感冒颗粒 ,头痛,清热,解表,利咽。"));
		String data2 = JsonUtil.obj2JsonData(new Medicine(2, "感冒  止咳糖浆", 31.2, "功能主治:感冒止咳糖浆,解表清热,止咳化痰。"));
		String data3 = JsonUtil.obj2JsonData(new Medicine(3, "感冒灵颗粒", 28.2, "功能主治:解热镇痛。头痛 ,清热。"));
		String data4 = JsonUtil.obj2JsonData(new Medicine(4, "感冒  灵胶囊", 19.8, "功能主治:银花感冒颗粒 ,头痛,清热,解表,利咽。"));
		String data5 = JsonUtil.obj2JsonData(new Medicine(5, "仁和 感冒 颗粒", 32.1, "功能主治:疏风清热,宣肺止咳,解表清热,止咳化痰。"));
		list.add(data1);
		list.add(data2);
		list.add(data3);
		list.add(data4);
		list.add(data5);
		return list;
	}
}

应用工具类

package org.dennisit.util;

import java.io.IOException;

import org.dennisit.entity.Medicine;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

public class JsonUtil {

	/**
	 * 实现将实体对象转换成json对象
	 * 
	 * @param medicine
	 *            Medicine对象
	 * @return
	 */
	public static String obj2JsonData(Medicine medicine) {
		String jsonData = null;
		try {
			// 使用XContentBuilder创建json数据
			XContentBuilder jsonBuild = XContentFactory.jsonBuilder();
			jsonBuild.startObject().field("id", medicine.getId()).field("name", medicine.getName()).field("funciton", medicine.getFunction()).endObject();
			jsonData = jsonBuild.string();
			System.out.println(jsonData);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jsonData;
	}

}

ElasticSearch 核心搜索模拟类

package org.dennisit.elastic.process;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.dennisit.entity.DataFactory;
import org.dennisit.entity.Medicine;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
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.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.FilterBuilders;
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.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;

public class ElasticSearchHandler {

	private Client client;

	public ElasticSearchHandler() {
		// 使用本机做为节点
		this("127.0.0.1");
	}

	public ElasticSearchHandler(String ipAddress) {
		client = new TransportClient().addTransportAddress(new InetSocketTransportAddress(ipAddress, 9300));
	}

	/**
	 * 建立索引,索引建立好之后,会在elasticsearch-rtf-master\data\elasticsearch\nodes\0创建所以你看
	 * 
	 * @param index
	 *            为索引库名,一个es集群中可以有多个索引库。 名称必须为小写
	 * @param type
	 *            Type为索引类型,是用来区分同索引库下不同类型的数据的,一个索引库下可以有多个索引类型。
	 * @param jsondata
	 *            json格式的数据集合
	 * 
	 * @return
	 */
	public void createIndexResponse(String index, String type, List<String> jsondata) {
		// 创建索引库
		List<IndexRequest> requests = new ArrayList<IndexRequest>();
		for (int i = 0; i < jsondata.size(); i++) {
			IndexRequest request = client.prepareIndex(index, type).setSource(jsondata.get(i)).request();
			requests.add(request);
		}

		// 批量创建索引
		BulkRequestBuilder bulkRequest = client.prepareBulk();
		for (IndexRequest request : requests) {
			bulkRequest.add(request);
		}

		BulkResponse bulkResponse = bulkRequest.execute().actionGet();
		if (bulkResponse.hasFailures()) {
			System.out.println("批量创建索引错误!");
		}
	}

	/**
	 * 创建索引
	 * 
	 * @param client
	 * @param jsondata
	 * @return
	 */
	public IndexResponse createIndexResponse(String indexname, String type, String jsondata) {
		IndexResponse response = client.prepareIndex(indexname, type).setSource(jsondata).execute().actionGet();
		return response;
	}

	/**
	 * 执行搜索
	 * 
	 * @param queryBuilder
	 * @param indexname
	 * @param type
	 * @return
	 */
	public List<Medicine> searcher(SearchRequestBuilder searchRequestBuilder, String indexname, String type) {
		List<Medicine> list = new ArrayList<Medicine>();
		SearchResponse searchResponse = searchRequestBuilder.setTypes(type).execute().actionGet();
		SearchHits hits = searchResponse.getHits();
		System.out.println("查询到记录数=" + hits.getTotalHits());
		SearchHit[] searchHists = hits.getHits();
		for (SearchHit hit : searchHists) {
			Integer id = (Integer) hit.getSource().get("id");
			String name = (String) hit.getSource().get("name");
			// 获取对应的高亮域
			Map<String, HighlightField> result = hit.highlightFields();
			// 从设定的高亮域中取得指定域
			HighlightField titleField = result.get("name");
			// 取得定义的高亮标签
			Text[] titleTexts = titleField.fragments();
			// 为title串值增加自定义的高亮标签
			String title = "";
			for (Text text : titleTexts) {
				title += text;
			}
			// 将追加了高亮标签的串值重新填充到对应的对象
			name = title;

			double price = (double) hit.getSource().get("price");
			String function = (String) hit.getSource().get("funciton");
			list.add(new Medicine(id, name, price, function));
		}
		return list;
	}

	// 根据索引名删除索引
	public boolean deleteIndex(String indexName) {
		try {
			QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
			client.prepareDeleteByQuery(indexName).setQuery(queryBuilder).execute().actionGet();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	// 根据数据id删除数据
	public boolean deleteData(String indexName, String typeName, String dataId) {
		try {
			// 设置线程:当删除api在同一个节点上执行时(在一个分片中执行一个api会分配到同一个服务器上),删除api允许执行前设置线程模式(operationThreaded选项),operationThreaded这个选项是使这个操作在另外一个线程中执行,或在一个正在请求的线程(假设这个api仍是异步的)中执行。默认的话operationThreaded会设置成true,这意味着这个操作将在一个不同的线程中执行。下面是设置成false的方法:
			DeleteResponse response = client.prepareDelete(indexName, typeName, dataId).setOperationThreaded(false).execute().actionGet();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	// 根据数据查询条件删除
	public boolean deleteData(String indexName, String typeName, QueryBuilder query) {
		try {
			client.prepareDeleteByQuery(indexName).setTypes(typeName).setQuery(query).execute().actionGet();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static void main(String[] args) {
		ElasticSearchHandler esHandler = new ElasticSearchHandler();
		List<String> jsondata = DataFactory.getInitJsonData();
		String indexName = "user";
		String typeName = "medicine";
		// 创建索引,追加方式
		// esHandler.createIndexResponse(indexname, type, jsondata);

		// 删除索引
		// esHandler.deleteIndex(indexname);

		// 查询条件
		SearchRequestBuilder searchRequestBuilder = esHandler.client.prepareSearch(indexName);
		// 设置查询关键词
		searchRequestBuilder.setQuery(QueryBuilders.wildcardQuery("name", "*感冒*"));
		// 设置高亮显示
		searchRequestBuilder.addHighlightedField("name");
		searchRequestBuilder.setHighlighterPreTags("<span style=\"color:red\">");
		searchRequestBuilder.setHighlighterPostTags("</span>");
		// 列条件过滤, 价格范围查询
		searchRequestBuilder.setPostFilter(FilterBuilders.rangeFilter("price").from(10).to(32));
		// 查询条数
		searchRequestBuilder.setFrom(0).setSize(6);
		// 排序
		searchRequestBuilder.addSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
		// 设置是否按查询匹配度排序
		searchRequestBuilder.setExplain(true);
		List<Medicine> result = esHandler.searcher(searchRequestBuilder, indexName, typeName);
		for (int i = 0; i < result.size(); i++) {
			Medicine medicine = result.get(i);
			System.out.println("(" + medicine.getId() + ")药品名称:" + medicine.getName() + "\t" + medicine.getPrice() + "\t" + medicine.getFunction());
		}
	}
}

启动 ElasticSearch(window  bin/elasticsearch.bat) 和redis

Windows下使用Java调用ElasticSearch提供的相关API进行数据搜索完整实例演示

程序运行前, 默认的 nodes 目录下没有内容 , 运行程序后会建立如下目录 

Windows下使用Java调用ElasticSearch提供的相关API进行数据搜索完整实例演示

控制台输出信息

{"id":1,"name":"银花 感冒 颗粒","funciton":"功能主治:银花感冒颗粒 ,头痛,清热,解表,利咽。"}
{"id":2,"name":"感冒  止咳糖浆","funciton":"功能主治:感冒止咳糖浆,解表清热,止咳化痰。"}
{"id":3,"name":"感冒灵颗粒","funciton":"功能主治:解热镇痛。头痛 ,清热。"}
{"id":4,"name":"感冒  灵胶囊","funciton":"功能主治:银花感冒颗粒 ,头痛,清热,解表,利咽。"}
{"id":5,"name":"仁和 感冒 颗粒","funciton":"功能主治:疏风清热,宣肺止咳,解表清热,止咳化痰。"}
查询到记录数=5(4)药品名称:感冒  灵胶囊        功能主治:银花感冒颗粒 ,头痛,清热,解表,利咽。
(1)药品名称:银花 感冒 颗粒        功能主治:银花感冒颗粒 ,头痛,清热,解表,利咽。
(2)药品名称:感冒  止咳糖浆        功能主治:感冒止咳糖浆,解表清热,止咳化痰。
(3)药品名称:感冒灵颗粒        功能主治:解热镇痛。头痛 ,清热。
(5)药品名称:仁和 感冒 颗粒        功能主治:疏风清热,宣肺止咳,解表清热,止咳化痰。


你可能感兴趣的:(Windows下使用Java调用ElasticSearch提供的相关API进行数据搜索完整实例演示)