原创

Elasticsearch 搜索服务器 Java API 使用详解

ElasticSearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。Elasticsearch 是用 Java 开发的,并作为Apache许可条款下的开放源码发布,是第二流行的企业搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。访问 ElasticSearch 的一个演示。网上的例子都是各个之间独立的,个别地方确实不好整合在一起来理解,希望通过此粗浅的例子能给使用java做搜索引擎的同学一些帮助。


使用环境,具体步骤如下:

1)JDK 1.6.0_29

2)ElasticSearch(0.20.2)-RTF,在谷歌中搜索 github 中下载。

3)Windows 7

4)ElasticSearch 访问用jar包.使用maven来添加如下:

      <dependency>
    	<groupId>org.elasticsearch</groupId>
    	<artifactId>elasticsearch</artifactId>
    	<version>0.20.2</version>
    </dependency>


ES的环境搭建具体步骤如下:

1)解压ElasticSearch(0.20.2)-RTF到某个目录,在本例中ESrtf解压到了两台电脑上(IP:192.168.1.232,IP:192.168.1.65)

2)在本例中因为使用的是rtf的版本,所以只需修改Eshome config目录下的elasticsearch.yml文件,在#cluster.name: elasticsearch这行下增加cluster.name: wallyCluster这行,作用为将es集群的默认名elasticsearch改为wallyCluster(自定义的集群名称).在#network.host: 127.0.0.1这行下增加network.host: 192.168.1.232(本例中es解压到了2台电脑中,所以另一台的应该为192.168.1.65),作用为绑定es启动时对外服务的ip,因为我所用的机子有多个网卡,所以指定了,如果是单网卡,可以不用这句设置。

3)在 eshome 下的bin目录中直接运行elasticsearch.bat(前提为必须设置好java的home环境变量)启动es,使用rtf版本进行开发,es基本不需要修改什么.至于es中使用到的内存大小设置,中文分词,cluster等等ES概念请百度。


网上看了各种例子,很大程度属于转载,讲到java API 的使用,都是简单的某个方面的使用,看ES官网介绍加自己的理解摸索,下面给出个完整使用javaapi的demo,Java API 的使用,具体代码如下:

import java.io.IOException;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

import com.wally.crj.util.TimeHelper;
public class ESMappingBiz {
	private Client client;
	
	public Client getClient() {
		return client;
	}
	public void setClient(Client client) {
		this.client = client;
	}
	/**
	 * 预定义一个索引的mapping,使用mapping的好处是可以个性的设置某个字段等的属性
	 * @throws Exception 
	 */
	public void buildIndexSysDm() throws Exception{
		//在本例中主要得注意,ttl及timestamp如何用java ,这些字段的具体含义,请去到es官网查看
		CreateIndexRequestBuilder cib=client.admin().indices().prepareCreate("productindex");
		XContentBuilder mapping = XContentFactory.jsonBuilder()
				.startObject()
					.startObject("we3r")//
						.startObject("_ttl")//有了这个设置,就等于在这个给索引的记录增加了失效时间,
											//ttl的使用地方如在分布式下,web系统用户登录状态的维护.
							.field("enabled",true)//默认的false的
							.field("default","5m")//默认的失效时间,d/h/m/s 即天/小时/分钟/秒
							.field("store","yes")
							.field("index","not_analyzed")
						.endObject()
						.startObject("_timestamp")//这个字段为时间戳字段.即你添加一条索引记录后,自动给该记录增加个时间字段(记录的创建时间),搜索中可以直接搜索该字段.
							.field("enabled",true)
							.field("store","no")
							.field("index","not_analyzed")
						.endObject()
						.startObject("properties")//properties下定义的title等等就是属于我们需要的自定义字段了,相当于数据库中的表字段 ,此处相当于创建数据库表
							.startObject("title").field("type", "string").field("store", "yes").endObject()    
							.startObject("description").field("type", "string").field("index", "not_analyzed").endObject()  
							.startObject("price").field("type", "double").endObject()  
							.startObject("onSale").field("type", "boolean").endObject()  
							.startObject("type").field("type", "integer").endObject()  
							.startObject("createDate").field("type", "date").field("format","YYYYMMddhhMMSS").endObject()
						.endObject()
					.endObject()
				.endObject();  
		cib.addMapping("prindextype", mapping);
		cib.execute().actionGet();
	}
	/**
	 * 该方法为增加索引记录
	 * @throws Exception
	 */
	public void buildIndexSysDm22() throws Exception{
		// productindex为上个方法中定义的索引,prindextype为类型.jk8231为id,以此可以代替memchche来进行数据的缓存
			 IndexResponse response = client.prepareIndex("productindex", "prindextype" ,"jk8231")
				        .setSource(XContentFactory.jsonBuilder()
				                    .startObject()
				                        .field("title", "abcd1")//该字段在上面的方法中mapping定义了,所以该字段就有了自定义的属性,比如 type等
				                        .field("description", "www.yoodb.com")
				                        .field("price", 1000 )
				                        .field("onSale",true)
				                        .field("type",2)
				                        .field("createDate",TimeHelper.getCurrentTime())
				                        .field("dfsfs","哈哈")//该字段在上面方法中的mapping中没有定义,所以该字段的属性使用es默认的.
				                    .endObject()
				                  )
				        .setTTL(8000)//这样就等于单独设定了该条记录的失效时间,单位是毫秒,必须在mapping中打开_ttl的设置开关
				        .execute()
				        .actionGet();
			 IndexResponse response2 = client.prepareIndex("productindex", "prindextype" ,"jk8234")
				        .setSource(XContentFactory.jsonBuilder()
				                    .startObject()
				                        .field("title", "abcd2")
				                        .field("description", "yoodb.com")
				                        .field("price", 1000 )
				                        .field("onSale",true)
				                        .field("type",22)
				                        .field("createDate",TimeHelper.getCurrentTime())
				                    .endObject()
				                  )
				        .execute()
				        .actionGet();
			 
	}
	/**
	 * 得到访问es的客户端,我们使用Transport Client
	 * @return
	 */
	public Client buildClient(){
		Settings settings = ImmutableSettings.settingsBuilder()
				.put("client.transport.sniff", true).put("cluster.name", "wallyCluster").build();
		Client client = new TransportClient(settings)
		.addTransportAddress(new InetSocketTransportAddress("192.168.1.232", 9300))
        .addTransportAddress(new InetSocketTransportAddress("192.168.1.65", 9300));
		return client;
	}
        /**
	 * 搜索的使用
	 */
	public void exm(){
		System.out.println("删除");
		DeleteResponse responsedd = client.prepareDelete("productindex", "prindextype", "34dds1")
		        .setOperationThreaded(false)
		        .execute()
		        .actionGet();
		System.out.println("根据主键搜索得到值");
		GetResponse responsere = client.prepareGet("productindex", "prindextype", "oht-Sp87SA6J5l3yo9dagw")
		        .execute()
		        .actionGet();
		System.out.println("完成读取--"+responsere.getSourceAsString());
		System.out.println("搜索");
		SearchRequestBuilder builder= client.prepareSearch("productindex")  //搜索productindex,prepareSearch(String... indices)注意该方法的参数,可以搜索多个索引
                .setTypes("prindextype")  
                .setSearchType(SearchType.DEFAULT)  
                .setFrom(0)  
                .setSize(50);  		
		 QueryBuilder qb2 = QueryBuilders.boolQuery() //  boolQuery() 就相当于 sql中的and
                   .must(new QueryStringQueryBuilder("素文宅").field("description"))//QueryStringQueryBuilder是单个字段的搜索条件,相当于组织sql的 where后面的字段名=字段值
                   .should(new QueryStringQueryBuilder("3").field("dfsfs")) 
		   .must(QueryBuilders .termQuery("dfsfs", "宅"));//关于QueryStringQueryBuilder及termQuery等的使用可以使用es插件head来进行操作体会个中query的不同
		 builder.setQuery(qb2);
		 SearchResponse responsesearch = builder.execute().actionGet(); 
		 System.out.println(""+responsesearch);
		try{String jsondata= responsesearch.getHits().getHits()[0].getSourceAsString();
		System.out.println("搜索出来的数据jsondata-- "+jsondata);
		}catch(Exception es){
			
		}
	}
	public static void main(String[] dfd){
		ESMappingBiz esm=new ESMappingBiz();
		esm.setClient(esm.buildClient());
		try {
//			esm.buildIndexSysDm();
			esm.buildIndexSysDm22();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			esm.getClient().close();
		}
	}
}

在开发中建议使用 ElasticSearch 的一些插件来查看 ElasticSearch 集群的即时信息,比如head(elasticsearch-head是一个elasticsearch的集群管理工具,它是完全由html5编写的独立网页程序,你可以通过插件把它集成到es),可以很直观的查看索引的信息,及组织json的查寻字符串等。

关注下方微信公众号“Java精选”(w_z90110),回复关键字领取资料:如HadoopDubboCAS源码等等,免费领取资料视频和项目。 

涵盖:程序人生、搞笑视频、算法与数据结构、黑客技术与网络安全、前端开发、Java、Python、Redis缓存、Spring源码、各大主流框架、Web开发、大数据技术、Storm、Hadoop、MapReduce、Spark、elasticsearch、单点登录统一认证、分布式框架、集群、安卓开发、iOS开发、C/C++、.NET、Linux、Mysql、Oracle、NoSQL非关系型数据库、运维等。

评论

分享:

支付宝

微信