ElaticSearch及IK分词器的使用

转发自https://blog.csdn.net/bipch/article/details/53364210

近日因工作原因使用了ElasticSearch(以下简称ES),因为是第一次使用,所以遇到了诸多困难。然而网络上的文章(主要指CSDN)绝大多数说的都是1.几的版本,与2.4版本相去甚远,并且关于JavaAPI的内容也比较少,说的都是命令行下的操作,不能应用于生产实际。笔者艰苦奋斗了近两天终于基本掌握了ES2.4.2的简单使用,分享如下,希望能让后来人少走一些弯路。

注:截至发稿时,ES的最新版本为5.0.1。对于没有使用5.0而使用2.4的原因,笔者将于文中有关位置作出解释,简单地说就是暂时还不好用。


1.安装ES

下载链接:https://www.elastic.co/downloads/past-releases/elasticsearch-2-4-2

笔者参与的项目应用于桌面程序,所以这里只介绍Windows环境下的内容。

将下载下来的压缩文件解压,路径不要太敏感,比如不要放在system32或者Program Files这种地方,以后用插件的时候可能java会出于安全考虑不允许读写这些路径的文件。

运行bin文件夹中的elasticsearch.bat,不要关掉,在浏览器中输入localhost:9200,如果返回一段包含集群信息的json即为安装成功。

这时可以用curl测试一下插入查询之类的命令,本文不介绍命令行内容,可参考官方文档https://www.elastic.co/guide/en/elasticsearch/guide/current/index.html

1.1测试ElaticSearch是否安装成功

http://127.0.0.1:9200/_analyze?analyzer=standard&pretty=true&text=我是中国人

2.安装ik分词插件(如果不使用ik分词可跳过这一部分)

下载链接:https://github.com/medcl/elasticsearch-analysis-ik/releases

项目主页中有ES与分词器版本的对应,ES2.4.2使用1.10.1版本的ik分词器。

关闭elasticsearch.bat,将下载下来的压缩文件解压,在ES目录中的plugins文件夹里新建名为ik的文件夹,将解压得到的所有文件复制到ik中。

将plugin-descriptor.properties文件中的2.4.1改为2.4.2。这是因为1.10.1版本的ik分词器是为2.4.1版本的ES设计的,如果不改这一项启动elasticsearch.bat的时候会抛出异常。笔者没有测试过5.0版本的ik能否用于2.4版本的ES。

在config文件夹中的elasticsearch.yml文件的最后加上index.analysis.analyzer.ik.type : "ik"

插件安装到此结束,网上其他文章说的往哪哪复制文件什么的都是老版本的ES需要的,2.4.2版本不需要。也有说用maven打包的,那个打不打包都可以,因为你下下来的压缩包就是打包后的结果,猜测是老版的ik没有release版本。

2.1测试ik分词器是否配置成功

http://127.0.0.1:9200/_analyze?analyzer=ik&pretty=true&text=我是中国人

ElaticSearch及IK分词器的使用_第1张图片


3.使用java添加索引

笔者不知道应该使用哪些jar包,笔者的处理方法是将所有的jar包都添加进工程。

实际上插入文档的时候ES会自动根据输入的index和type创建相应的index和type,但是因为我们要使用ik分词器,所以我们需要设置一下index的属性,而不能自动创建。所以不使用ik分词也可以跳过这一部分。

[java]  view plain  copy
  1. "font-size:14px;">package main;  
  2.   
  3. import java.net.InetAddress;  
  4. import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;  
  5. import org.elasticsearch.client.Client;  
  6. import org.elasticsearch.client.Requests;  
  7. import org.elasticsearch.client.transport.TransportClient;  
  8. import org.elasticsearch.common.transport.InetSocketTransportAddress;  
  9. import org.elasticsearch.common.xcontent.XContentBuilder;  
  10. import org.elasticsearch.common.xcontent.XContentFactory;  
  11.   
  12. public class CreatIndex  
  13. {  
  14.     /** 
  15.      * 创建mapping(feid("indexAnalyzer","ik")该字段分词IK索引 ;feid("searchAnalyzer","ik")该字段分词ik查询;具体分词插件请看IK分词插件说明) 
  16.      * @param indices 索引名称; 
  17.      * @param mappingType 类型 
  18.      * @throws Exception 
  19.      */  
  20.     public static void createMapping(String indices,String mappingType)throws Exception{  
  21.         Client client = TransportClient.builder().build()  
  22.                 .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));  
  23.           
  24.         client.admin().indices().prepareCreate(indices).execute().actionGet();  
  25.         new XContentFactory();  
  26.         XContentBuilder builder=XContentFactory.jsonBuilder()  
  27.                 .startObject()  
  28.                 .startObject(mappingType)  
  29.                 .startObject("properties")  
  30.                 .startObject("title").field("type""string").field("store""yes").field("analyzer","ik").field("index","analyzed").endObject()  
  31.                 .startObject("content").field("type""string").field("store""yes").field("analyzer","ik").field("index","analyzed").endObject()  
  32.                 .endObject()  
  33.                 .endObject()  
  34.                 .endObject();  
  35.         PutMappingRequest mapping = Requests.putMappingRequest(indices).type(mappingType).source(builder);  
  36.           
  37.         client.admin().indices().putMapping(mapping).actionGet();  
  38.         client.close();  
  39.     }  
  40. }  

    这里设置title和content两个字段,type属性根据自己的需要设置,据说store是可有可无的。

    注意index的创建只能执行一次,如果执行前index已经存在,那么就会抛出异常,并不会更改设置。


4.插入和检索文档

[java]  view plain  copy
  1. "font-size:14px;">package main;  
  2. import java.io.BufferedReader;  
  3.   
  4. import java.io.File;  
  5. import java.io.FileReader;  
  6. import java.io.IOException;  
  7. import java.net.InetAddress;  
  8. import java.net.UnknownHostException;  
  9. import java.util.HashMap;  
  10. import java.util.List;  
  11. import java.util.Map;  
  12.   
  13. import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction;  
  14. import org.elasticsearch.action.admin.indices.analyze.AnalyzeRequestBuilder;  
  15. import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse.AnalyzeToken;  
  16. import org.elasticsearch.action.index.IndexResponse;  
  17. import org.elasticsearch.client.Client;  
  18. import org.elasticsearch.client.transport.TransportClient;  
  19. import org.elasticsearch.common.transport.InetSocketTransportAddress;  
  20. import org.elasticsearch.action.search.SearchResponse;  
  21. import org.elasticsearch.index.query.BoolQueryBuilder;  
  22. import org.elasticsearch.index.query.QueryBuilder;  
  23. import org.elasticsearch.index.query.QueryBuilders;  
  24. import org.elasticsearch.index.query.QueryStringQueryBuilder;  
  25. import org.elasticsearch.search.SearchHit;  
  26. import org.elasticsearch.search.SearchHits;  
  27.   
  28. import static org.elasticsearch.index.query.QueryBuilders.*;  
  29.   
  30. public class main  
  31. {  
  32.     /** 
  33.      * @param args 
  34.      */  
  35.     public static void main(String[] args)  
  36.     {  
  37.         // TODO Auto-generated method stub  
  38.         IndexResponse response=null;  
  39.         Client client=null;  
  40.         Map json=new HashMap();//构建json  
  41.         json.put("title""novel");  
  42.         json.put("content""the content");  
  43.           
  44.         try  
  45.         {  
  46.             CreatIndex.createMapping("test""text");//创建index和type  
  47.         } catch (Exception e1)  
  48.         {  
  49.             // TODO Auto-generated catch block  
  50.             e1.printStackTrace();  
  51.         }  
  52.            
  53.           
  54.         // client startup  
  55.         try  
  56.         {  
  57.             client = TransportClient.builder().build()//新建客户端  
  58.                     .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));  
  59.             response = client.prepareIndex("test""text","1")//插入文档,参数依次为index、type、id  
  60.                     .setSource(json).get();  
  61.           
  62.         } catch (UnknownHostException e)  
  63.         {  
  64.             // TODO Auto-generated catch block  
  65.             e.printStackTrace();  
  66.         } catch (IOException e)  
  67.         {  
  68.             // TODO Auto-generated catch block  
  69.             e.printStackTrace();  
  70.         }  
  71.         // Index name  
  72.         String _index = response.getIndex();  
  73.         // Type name  
  74.         String _type = response.getType();  
  75.         // Document ID (generated or not)  
  76.         String _id = response.getId();  
  77.         // Version (if it's the first time you index this document, you will get: 1)  
  78.         long _version = response.getVersion();  
  79.         // isCreated() is true if the document is a new one, false if it has been updated  
  80.         boolean created = response.isCreated();//插入后返回的信息可以通过response获取  
  81.         System.out.println("index:"+_index);  
  82.         System.out.println("type:"+_type);  
  83.         System.out.println("id:"+_id);  
  84.         System.out.println("version:"+_version);  
  85.         System.out.println("created:"+created);  
  86.           
  87.         //查询  
  88.         QueryBuilder qb= matchQuery("content""前后不到");   
  89.   
  90.         SearchResponse searchresponse = client.prepareSearch("test")//index  
  91.                                         .setTypes("text")//type  
  92.                                         .setQuery(qb)//query  
  93.                                         .addHighlightedField("content")//高亮字段  
  94.                                         .setHighlighterPreTags("")//设置搜索条件前后标签  
  95.                                 .setHighlighterPostTags("")  
  96.                                 .setHighlighterFragmentSize(50)//返回的高亮部分上下文长度  
  97.                                         .execute()  
  98.                                         .actionGet();  
  99.   
  100.         SearchHits hits = searchresponse.getHits();//获取返回值  
  101.         if (hits.totalHits() > 0) {  
  102.             for (SearchHit hit : hits) {  
  103.                 System.out.println("score:"+hit.getScore()+":\t"+hit.getId());// .get("title").getSource()  
  104.                 System.out.println("content:"+hit.getHighlightFields());  
  105.             }  
  106.         } else {  
  107.             System.out.println("搜到0条结果");  
  108.         }  
  109.         client.close();  
  110.           
  111.     }  
  112.   
  113. }  

          过程为:新建index-新建客户端-建立搜索条件-发送搜索请求-建立查询条件-发送查询请求

        其中,新建客户端时,ES5.0的API和ES2.4之前的API是不一样的,而ES5.0的API使用时会报找不到方法的错,不知道是API写错了还是jar包给少了,总之是不能用,所以笔者没有使用更新的5.0版本。


你可能感兴趣的:(ElaticSearch及IK分词器的使用)