您的位置:首页 > 编程语言 > Java开发

ElasticSearch2.4.2+ik分词+java简单使用

2016-11-27 14:01 363 查看
近日因工作原因使用了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

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版本。

3.使用java添加索引

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

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

package main;

import java.net.InetAddress;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

public class CreatIndex
{
/**
* 创建mapping(feid("indexAnalyzer","ik")该字段分词IK索引 ;feid("searchAnalyzer","ik")该字段分词ik查询;具体分词插件请看IK分词插件说明)
* @param indices 索引名称;
* @param mappingType 类型
* @throws Exception
*/
public static void createMapping(String indices,String mappingType)throws Exception{
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

client.admin().indices().prepareCreate(indices).execute().actionGet();
new XContentFactory();
XContentBuilder builder=XContentFactory.jsonBuilder()
.startObject()
.startObject(mappingType)
.startObject("properties")
.startObject("title").field("type", "string").field("store", "yes").field("analyzer","ik").field("index","analyzed").endObject()
.startObject("content").field("type", "string").field("store", "yes").field("analyzer","ik").field("index","analyzed").endObject()
.endObject()
.endObject()
.endObject();
PutMappingRequest mapping = Requests.putMappingRequest(indices).type(mappingType).source(builder);

client.admin().indices().putMapping(mapping).actionGet();
client.close();
}
}

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

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

4.插入和检索文档

package main;
import java.io.BufferedReader;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeRequestBuilder;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse.AnalyzeToken;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
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.SearchHits;

import static org.elasticsearch.index.query.QueryBuilders.*;

public class main
{
/**
* @param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
IndexResponse response=null;
Client client=null;
Map<String, Object> json=new HashMap<String, Object>();//构建json
json.put("title", "novel");
json.put("content", "the content");

try
{
CreatIndex.createMapping("test", "text");//创建index和type
} catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}

// client startup
try
{
client = TransportClient.builder().build()//新建客户端
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
response = client.prepareIndex("test", "text","1")//插入文档,参数依次为index、type、id
.setSource(json).get();

} catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
// Index name
String _index = response.getIndex();
// Type name
String _type = response.getType();
// Document ID (generated or not)
String _id = response.getId();
// Version (if it's the first time you index this document, you will get: 1)
long _version = response.getVersion();
// isCreated() is true if the document is a new one, false if it has been updated
boolean created = response.isCreated();//插入后返回的信息可以通过response获取
System.out.println("index:"+_index);
System.out.println("type:"+_type);
System.out.println("id:"+_id);
System.out.println("version:"+_version);
System.out.println("created:"+created);

//查询
QueryBuilder qb= matchQuery("content", "前后不到");

SearchResponse searchresponse = client.prepareSearch("test")//index
.setTypes("text")//type
.setQuery(qb)//query
.addHighlightedField("content")//高亮字段
.setHighlighterPreTags("<b>")//设置搜索条件前后标签
.setHighlighterPostTags("</b>")
.setHighlighterFragmentSize(50)//返回的高亮部分上下文长度
.execute()
.actionGet();

SearchHits hits = searchresponse.getHits();//获取返回值
if (hits.totalHits() > 0) {
for (SearchHit hit : hits) {
System.out.println("score:"+hit.getScore()+":\t"+hit.getId());// .get("title").getSource()
System.out.println("content:"+hit.getHighlightFields());
}
} else {
System.out.println("搜到0条结果");
}
client.close();

}

}


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

        其中,新建客户端时,ES5.0的API和ES2.4之前的API是不一样的,而ES5.0的API使用时会报找不到方法的错,不知道是API写错了还是jar包给少了,总之是不能用,所以笔者没有使用更新的5.0版本。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  elasticsearch java ik