安装包elasticsearch-rtf下载
elasticsearch中文发行版,针对中文集成了相关插件(包含ik analyzer),并带有Demo,方便新手学习,或者在生产环境中直接使用
redis下载
http://pan.baidu.com/s/1kTD2XG7
官方视频教程
http://www.elasticsearch.org/videos/
Window 环境
下载完解开有以下个包 :
bin 是运行的脚本, config 是设置文件, lib 是放依赖的包。
启动解压目录下的 bin 名称的文件夹,双击 elasticsearch.bat 文件,就可以启动 elasticsearch ,启动成功界面如下 :
启动成功后 , 会在解压目录下增加 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
程序运行前, 默认的 nodes 目录下没有内容 , 运行程序后会建立如下目录
控制台输出信息
{"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)药品名称:仁和 感冒 颗粒 功能主治:疏风清热,宣肺止咳,解表清热,止咳化痰。