ElasticSearch入门-搜索如此简单

2019-03-11 09:16|来源: 网络

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

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

第二、like的不能做到完全的模糊匹配。比如like '%化痰冲剂%'就不能把”化痰止咳冲剂“搜索出来。但是普通的用户,需求就是这样

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

种种原因导致搜索引擎的横空出世。

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

Java代码
  1. import org.elasticsearch.action.bulk.BulkRequestBuilder;  

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

  3. import org.elasticsearch.action.index.IndexRequestBuilder;  

  4. import org.elasticsearch.client.Client;  

  5.  

  6. import com.donlianli.es.ESUtils;  

  7. import com.donlianli.es.model.LogModel;  

  8.  

  9. public class BulkIndexTest {  

  10.      

  11.    public static void main(String[] args) {  

  12.        String[] desc = new String[]{  

  13.                "玉屏风口服液",  

  14.                "清咽丸",  

  15.                "四消丸",  

  16.                "感冒清胶囊",  

  17.                "人参归脾丸",  

  18.                  

  19.                "人参健脾丸",  

  20.                "明目地黄丸",  

  21.                "小儿咳喘灵颗粒",  

  22.                "小儿化痰止咳冲剂",  

  23.                "双黄连",  

  24.                "六味地黄丸"  

  25.        };  

  26.        Client client = ESUtils.getClient();  

  27.        int j= 0;  

  28.        BulkRequestBuilder bulkRequest = client.prepareBulk();  

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

  30.            LogModel l = new LogModel();  

  31.            l.setDesc(desc[j]);  

  32.            j++;  

  33.            String json = ESUtils.toJson(l);  

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

  35.            //指定不重复的ID        

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

  37.            //添加到builder中  

  38.            bulkRequest.add(indexRequest);  

  39.        }  

  40.          

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

  42.        if (bulkResponse.hasFailures()) {  

  43.            // process failures by iterating through each bulk response item  

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

  45.        }  

  46.    }  

  47. }  

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

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

下面,我们需要对LogModel的desc字段进行搜索。我们搜索一个最简单的”丸“字,我们希望将所有带丸字的记录都筛选出来。

Java代码
  1. import org.elasticsearch.action.search.SearchResponse;  

  2. import org.elasticsearch.client.Client;  

  3. import org.elasticsearch.index.query.QueryBuilder;  

  4. import org.elasticsearch.index.query.QueryBuilders;  

  5. import org.elasticsearch.search.SearchHit;  

  6. import org.elasticsearch.search.SearchHits;  

  7.  

  8. import com.donlianli.es.ESUtils;  

  9.  

  10. public class QuerySearchTest {  

  11.    public static void main(String[] args) {  

  12.        Client client = ESUtils.getClient();  

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

  14.        SearchResponse response = client.prepareSearch("twitter")  

  15.                .setTypes("tweet")  

  16.                //设置查询条件,  

  17.                .setQuery(query)  

  18.                .setFrom(0).setSize(60)  

  19.                .execute()  

  20.                .actionGet();  

  21.        /**

  22.         * SearchHits是SearchHit的复数形式,表示这个是一个列表

  23.         */  

  24.        SearchHits shs = response.getHits();  

  25.        for(SearchHit hit : shs){  

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

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

  28.        }  

  29.        client.close();  

  30.    }  

  31.  

  32. }  

运行结果:

分数(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的客户端。

Java代码
  1. public static Client getClient(){  

  2.        Settings settings = ImmutableSettings.settingsBuilder()  

  3.                //指定集群名称  

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

  5.                //探测集群中机器状态  

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

  7.        /*

  8.         * 创建客户端,所有的操作都由客户端开始,这个就好像是JDBC的Connection对象

  9.         * 用完记得要关闭

  10.         */  

  11.        Client client = new TransportClient(settings)  

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

  13.        return client;  

  14.    }  


对这类话题感兴趣?欢迎发送邮件至 donlianli@126.com    
关于我:邯郸人,擅长Java,Javascript,Extjs,oracle sql。    
更多我之前的文章,可以访问  我的空间    

 
转自:http://donlianli.iteye.com/blog/1904064

相关问答

更多