ElasticSearch入门-搜索如此简单

搜索引擎我也不是很熟悉,可是数据库仍是比较了解。能够把搜索理解为数据库的like功能的替代品。由于like有如下几点不足:数据库

第1、like的效率不行,在使用like时,通常都用不到索引,除非使用前缀匹配,才能用得上索引。但普通的需求并不是前缀匹配。json

第2、like的不能作到彻底的模糊匹配。好比like '%化痰冲剂%'就不能把”化痰止咳冲剂“搜索出来。可是普通的用户,需求就是这样elasticsearch

第3、like没法根据匹配度进行排序。数据库匹配某个关键字的记录可能有好几千,可是用户只能看100条,数据库每每返回用户一些不关心的记录。ui

种种缘由致使搜索引擎的横空出世。搜索引擎

为了说明ES的搜索AIP及搜索功能,咱们须要先造点数据。spa

import org.elasticsearch.action.bulk.BulkRequestBuilder;orm

import org.elasticsearch.action.bulk.BulkResponse;blog

import org.elasticsearch.action.index.IndexRequestBuilder;排序

import org.elasticsearch.client.Client;索引

import com.donlianli.es.ESUtils;

import com.donlianli.es.model.LogModel;

public class BulkIndexTest {

public static void main(String[] args) {

String[] desc = new String[]{

"玉屏风口服液",

"清咽丸",

"四消丸",

"感冒清胶囊",

"人参归脾丸",

"人参健脾丸",

"明目地黄丸",

"小儿咳喘灵颗粒",

"小儿化痰止咳冲剂",

"双黄连",

"六味地黄丸"

};

Client client = ESUtils.getClient();

int j= 0;

BulkRequestBuilder bulkRequest = client.prepareBulk();

for(int i=1000;i<1010;i++){

LogModel l = new LogModel();

l.setDesc(desc[j]);

j++;

String json = ESUtils.toJson(l);

IndexRequestBuilder indexRequest = client.prepareIndex("twitter", "tweet")

//指定不重复的ID

       .setSource(json).setId(String.valueOf(i));

//添加到builder中

bulkRequest.add(indexRequest);

}

BulkResponse bulkResponse = bulkRequest.execute().actionGet();

if (bulkResponse.hasFailures()) {

   // process failures by iterating through each bulk response item

System.out.println(bulkResponse.buildFailureMessage());

}

}

}

LogModel的定义见ElasticSearch入门-增删改查(CRUD)

咱们插入了10条记录到ES,别管ID是多少,只要不重就行。

下面,咱们须要对LogModel的desc字段进行搜索。咱们搜索一个最简单的”丸“字,咱们但愿将全部带丸字的记录都筛选出来。

import org.elasticsearch.action.search.SearchResponse;

import org.elasticsearch.client.Client;

import org.elasticsearch.index.query.QueryBuilder;

import org.elasticsearch.index.query.QueryBuilders;

import org.elasticsearch.search.SearchHit;

import org.elasticsearch.search.SearchHits;

import com.donlianli.es.ESUtils;

public class QuerySearchTest {

public static void main(String[] args) {

Client client = ESUtils.getClient();

QueryBuilder query = QueryBuilders.fieldQuery("desc", "丸");

SearchResponse response = client.prepareSearch("twitter")

.setTypes("tweet")

//设置查询条件,

       .setQuery(query)

       .setFrom(0).setSize(60)

       .execute()

       .actionGet();

SearchHits shs = response.getHits();

for(SearchHit hit : shs){

System.out.println("分数(score):"+hit.getScore()+", 业务描述(desc):"+

hit.getSource().get("desc"));

}

client.close();

}

}

运行结果:

分数(score):2.97438, 业务描述(desc):四消丸

分数(score):2.7716475, 业务描述(desc):清咽丸

分数(score):2.6025825, 业务描述(desc):人参归脾丸

分数(score):2.6025825, 业务描述(desc):人参健脾丸

分数(score):2.4251914, 业务描述(desc):明目地黄丸

能够看到,搜索引擎已经将咱们全部带丸的记录都筛选出来了。而且,字数最少的自动排在了最前面。是否是很智能。在彻底没有配置ES任何东西以前,就能使用搜索功能了。

下面,咱们再来试试搜索”小儿颗粒“,你猜会不会搜到记录呢?运行结果:

分数(score):4.46157, 业务描述(desc):小儿咳喘灵颗粒

分数(score):0.87699485, 业务描述(desc):小儿化痰止咳冲剂

嗯,不错,虽然没有彻底匹配的,但相关记录都已经出来了。

至此,使用ES替代数据库的LIKE功能,基本上已经完成了。搜索的更多功能,探索ing。。。。

PS: ESUtils.getClient();就是一个静态方法,建立了一个ES的客户端。

public static Client getClient(){

Settings settings = ImmutableSettings.settingsBuilder()

//指定集群名称

                .put("cluster.name", "elasticsearch")

                //探测集群中机器状态

                .put("client.transport.sniff", true).build();

Client client = new TransportClient(settings)

.addTransportAddress(new InetSocketTransportAddress("192.168.1.106", 9300));

return client;

}

相关文章
相关标签/搜索