分布式搜索elasticsearch java API

来源:互联网 发布:免费top域名 编辑:程序博客网 时间:2024/04/30 03:04

 Mapping,就是对索引库中索引的字段名及其数据类型进行定义,类似于关系数据库中表建立时要定义字段名及其数据类型那样,不过es的mapping比数据库灵活很多,它可以动态添加字段。一般不需要要指定mapping都可以,因为es会自动根据数据格式定义它的类型,如果你需要对某些字段添加特殊属性(如:定义使用其它分词器、是否分词、是否存储等),就必须手动添加mapping。有两种添加mapping的方法,一种是定义在配置文件中,一种是运行时手动提交mapping,两种选一种就行了。

         先介绍在配置文件中定义mapping,你可以把[mapping名].json文件放到config/mappings/[索引名]目录下,这个目录要自己创建,一个mapping和一个索引对应,你也可以定义一个默认的mapping,把自己定义的default-mapping.json放到config目录下就行。json格式如下:

{
"mappings":{
"properties":{
"title":{
"type":"string",
"store":"yes"
},
"description":{
"type":"string",
"index":"not_analyzed"
},
"price":{
"type":"double"
},
"onSale":{
"type":"boolean"
},
"type":{
"type":"integer"
},
"createDate":{
"type":"date"
}
}
}
}

  接下来介绍通过请求添加mapping,下面为一个添加productIndex索引库的mapping的json格式请求。其中productIndex为索引类型,properties下面的为索引里面的字段,type为数据类型,store为是否存储,"index":"not_analyzed"为不对该字段进行分词。

 

{
"productIndex":{
"properties":{
"title":{
"type":"string",
"store":"yes"
},
"description":{
"type":"string",
"index":"not_analyzed"
},
"price":{
"type":"double"
},
"onSale":{
"type":"boolean"
},
"type":{
"type":"integer"
},
"createDate":{
"type":"date"
}
}
}
}

 

先创建空索引库

 client.admin().indices().prepareCreate("productIndex").execute().actionGet();  



put mapping



 

XContentBuilder mapping = jsonBuilder()
.startObject()
.startObject("productIndex")
.startObject("properties") 
.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").endObject() 
.endObject()
.endObject()
.endObject();
PutMappingRequest mappingRequest = Requests.putMappingRequest("productIndex").type("productIndex").source(mapping);
client.admin().indices().putMapping(mappingRequest).actionGet();

 

es索引数据非常方便,只需构建个json格式的数据提交到es就行,下面是个java api的例子

 

XContentBuilder doc = jsonBuilder()
.startObject() 
.field("title", "this is a title!")
.field("description", "descript what?") 
.field("price", 100)
.field("onSale", true)
.field("type", 1)
.field("createDate", new Date()) 
.endObject();
client.prepareIndex("productIndex","productType").setSource(doc).execute().actionGet();

其中productIndex为索引库名,一个es集群中可以有多个索引库。productType为索引类型,是用来区分同索引库下不同类型的数据的,一个索引库下可以有多个索引类型。



 删除api允许从特定索引通过id删除json文档。有两种方法,一是通过id删除,二是通过一个Query查询条件删除,符合这些条件的数据都会被删除。

 

一、通过id删除

 

下面的例子是删除索引名为twitter,类型为tweet,id为1的文档:

DeleteResponse response = client.prepareDelete("twitter", "tweet", "1") 
.execute() 
.actionGet();

二、通过Query删除

下面的例子是删除索引名为productIndex,title中包含query的所有文档:

QueryBuilder query = QueryBuilders.fieldQuery("title", "query");
client.prepareDeleteByQuery("productIndex").setQuery(query).execute().actionGet();

设置线程
       当删除api在同一个节点上执行时(在一个分片中执行一个api会分配到同一个服务器上),删除api允许执行前设置线程模式(operationThreaded选项),operationThreaded这个选项是使这个操作在另外一个线程中执行,或在一个正在请求的线程(假设这个api仍是异步的)中执行。默认的话operationThreaded会设置成true,这意味着这个操作将在一个不同的线程中执行。下面是设置成false的方法:

 

DeleteResponse response = client.prepareDelete("twitter", "tweet", "1") 
.setOperationThreaded(false) 
.execute() 
.actionGet();

 

 

elasticsearch的查询是通过执行json格式的查询条件,在java api中就是构造QueryBuilder对象,elasticsearch完全支持queryDSL风格的查询方式,QueryBuilder的构建类是QueryBuilders,filter的构建类是FilterBuilders。下面是构造QueryBuilder的例子:

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

QueryBuilder qb1 = termQuery("name", "kimchy"); 

QueryBuilder qb2 = boolQuery() 
.must(termQuery("content", "test1")) 
.must(termQuery("content", "test4")) 
.mustNot(termQuery("content", "test2")) 
.should(termQuery("content", "test3")); 

QueryBuilder qb3 = filteredQuery( 
termQuery("name.first", "shay"), 
rangeFilter("age") 
.from(23) 
.to(54) 
.includeLower(true) 
.includeUpper(false) 
);

 

其中qb1构造了一个TermQuery,对name这个字段进行项搜索,项是最小的索引片段,这个查询对应lucene本身的TermQuery。 qb2构造了一个组合查询(BoolQuery),其对应lucene本身的BooleanQuery,可以通过must、should、mustNot方法对QueryBuilder进行组合,形成多条件查询。 qb3构造了一个过滤查询,就是在TermQuery的基础上添加一个过滤条件RangeFilter,这个范围过滤器将限制查询age字段大于等于23,小于等于54的结果。除了这三个,elasticsearch还支持很多种类的查询方式,迟点写个介绍。

构造好了Query就要传到elasticsearch里面进行查询,下面是例子:

SearchResponse response = client.prepareSearch("test") 
.setQuery(query) 
.setFrom(0).setSize(60).setExplain(true) 
.execute() 
.actionGet();

 

这句的意思是,查询test索引,查询条件为query,从第0条记录开始,最多返回60条记录。返回结果为SearchResponse,下面解析SearchResponse:

 

SearchHits hits = searchResponse.hits();
for (int i = 0; i < 60; i++) {
System.out.println(hits.getAt(i).getSource().get("field"));
}

获得SearchResponse中的SearchHits,然后hits.getAt(i).getSource().get("field")获得field字段的值。

0 0
原创粉丝点击