zoukankan      html  css  js  c++  java
  • ElasticSearch入门-搜索如此简单

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

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

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

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

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

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

    import org.elasticsearch.action.bulk.BulkRequestBuilder;  
    import org.elasticsearch.action.bulk.BulkResponse;  
    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是SearchHit的复数形式,表示这个是一个列表 
             */  
            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();  
            /* 
             * 创建客户端,所有的操作都由客户端开始,这个就好像是JDBC的Connection对象 
             * 用完记得要关闭 
             */  
            Client client = new TransportClient(settings)  
            .addTransportAddress(new InetSocketTransportAddress("192.168.1.106", 9300));  
            return client;  
        }  
    对这类话题感兴趣?欢迎发送邮件至donlianli@126.com;或者关注我的微信公众号“猿界汪汪队”
    关于我:邯郸人,擅长Java,Javascript,Extjs,oracle sql。
  • 相关阅读:
    Druid时序数据库常见问题及处理方式
    常用环境变量配置
    Hadoop学习(四) FileSystem Shell命令详解
    Hadoop学习(二) Hadoop配置文件参数详解
    Hadoop学习(一) Hadoop是什么
    Sqoop帮助文档
    CentOS搭建Sqoop环境
    Zookeeper系列(二) Zookeeper配置说明
    查看sql 作业明细及运行记录
    java性能测试工具 jprofiler
  • 原文地址:https://www.cnblogs.com/donlianli/p/3189047.html
Copyright © 2011-2022 走看看