• Elasticsearch java api 基本搜索部分详解


    文档是结合几个博客整理出来的,内容大部分为转载内容。在使用过程中,对一些疑问点进行了整理与解析。

    Elasticsearch java api 基本搜索部分详解

    ElasticSearch 常用的查询过滤语句

    一、所使用版本的介绍

    使用的是elasticsearch2.4.3版本,在此只是简单介绍搜索部分的api使用

    二、简单的搜索

    使用api的时候,基本上可以将DSL搜索的所有情况均写出来,在此给出一个最简单搜索的全部的过程以及代码,之后将对不同的搜索只是针对函数进行介绍

    (1)DSL搜索

    对于最简单的DSL搜索,对一个词进行搜索使用url直接进行通信,例如,如果对于一个字段,

    搜索具体的一个term或者query,DSL如下所示:

    {“query”:{"term":{"title":"molong1208 blog"}}}

    这个搜索的含义是:在title字段,搜索内容为molong1208 blog;上面是DSL的写法,实际上对于简单的查询,也可以直接使用url查询,不带json格式,假设我们所使用的服务器ip是localhost,对于如上的查询可以写为: 

    localhost:9200/index/type/_search? q=title:molong1208 blog

    这个写法与上边的DSL语言是同样的功能的,但是这种写法只是一些简单的查询才可以用,例如显示想要的字段,按照某一字段排序等

    localhost:9200/index/type/_search? q=title:molong1208 blog&fields=name,title&sort=id:desc&pretty=true

    上述url的意思就是在index/type里面的title字段搜索内容,并且显示的字段为name以及title,按照id降序排序,输出的格式为美化的json格式

    (2)使用java api 实现简单搜索

    1、建立连接

    java api使用搜索的时候,必须先进行连接,在直接url的时候是端口9200,但是在使用程序的时候为9300,如下所示,建立客户端的连接,在connection类里面给出初始化函数

     1     private static void open()  
     2         {  
     3                 Settings settings = Settings.settingsBuilder()  
     4                         .put("cluster.name", "molong").build();  
     5                           
     6                 try {  
     7                     client =  TransportClient.builder().settings(settings).build()  
     8                             .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));  
     9                 } catch (UnknownHostException e) {  
    10                     // TODO Auto-generated catch block  
    11                     e.printStackTrace();  
    12                 }  
    13       
    14         }  

    在此使用的是TransportClient连接,还有一个Nodeclient,没使用过,在此不做介绍

    2、进行查询

    查询的时候,需要建立一个SearchRequestBuilder,这里面将给出对于哪一个index或者type进行查询,并且所有的设置都可以在这里面进行实现,例如模糊查询,范围查询,前缀查询等

    SearchRequestBuilder responsebuilder = client.prepareSearch("index").setTypes("type") 
    

    上述代码的意思是对于index的type进行查询,其中client即使得到的建立链接,下一步就是要将查询词给进去

        SearchResponse myresponse=responsebuilder.setQuery(
        		QueryBuilders.matchPhraseQuery("title", "molong1208 blog"))  
        .setFrom(0).setSize(10).setExplain(true).execute().actionGet();  
    

    3、展示

        SearchHits hits = myresponse.getHits();  
        for (int i = 0; i < hits.getHits().length; i++) {  
                   System.out.println(hits.getHits()[i].getSourceAsString());}  
    

    4、常用的方法说明

    setFrom(0):类似于分页的下标、索引,默认为0
    setSize(10):分页的每页展示的数量,默认为10

    三、搜索时其他api的实现

    读DSL的时候我们可以看到,查询有很多的查询,比如说多域,比如说过滤等查询条件,下面就针对 Elasticsearch服务器开发中一些基本查询的DSL给出在java api实现的一些形式,其中很多形式不同的之处只是上述塞查询词时候的setQuery里面的不同,所以在此只是讲述里面的函数不同

    (1)基本查询

    1         SearchResponse myresponse=responsebuilder.setQuery(                
    2                 //1.基本查询
    3                 QueryBuilders.matchPhraseQuery("name", "岳云鹏18")                
    4                 )  
    5                 .setFrom(0).setSize(10)
    6 //                .setExplain(true)
    7                 .execute().actionGet();  

    matchPhraseQuery(String name, Object text):name表示字段名称,text表示字段所对应的内容。

    (2)多词条查询

    1 SearchResponse myresponse=responsebuilder.setQuery(                
    2                 //2.多词条查询 ?
    3                 //term主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型): 
    4                 QueryBuilders.termsQuery("levle","3","2")            
    5                 )  
    6                 .setFrom(0).setSize(10)
    7 //                .setExplain(true)
    8                 .execute().actionGet();  

    term主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型)

    详情参考:ElasticSearch 常用的查询过滤语句

    (3)match_all查询

    1 SearchResponse myresponse=responsebuilder.setQuery(                
    2                 //3.查询全部
    3                 QueryBuilders.matchAllQuery()          
    4                 )  
    5                 .setFrom(0).setSize(100)
    6 //                .setExplain(true)
    7                 .execute().actionGet();  

    有点类似于mysql语法:select * from tableName

    (4)常用词查询

    1 SearchResponse myresponse=responsebuilder.setQuery(                
    2                 //4.常用词查询
    3                 QueryBuilders.commonTermsQuery("name", "岳云鹏18")        
    4                 )  
    5                 .setFrom(0).setSize(100)
    6 //                .setExplain(true)
    7                 .execute().actionGet();  

    个人觉得与(1)基本查询matchPhraseQuery(String name, Object text)类似

    (5)match查询

    只使用过matchPhraseQuery函数,具体用法见上述所示

    (6)multi_match查询

    1 SearchResponse myresponse=responsebuilder.setQuery(                
    2                 //6.multiMatchQuery(text,fields)其中的fields是字段的名字,可以写好几个,每一个中间用逗号分隔 
    3                 QueryBuilders.multiMatchQuery("13", "name","address")    
    4                 )  
    5                 .setFrom(0).setSize(100)
    6 //                .setExplain(true)
    7                 .execute().actionGet();  

    multiMatchQuery(Object text, String... fieldNames):text为文本值,fieldNames为字段名称。

    举例说明:name、address为字段名称,13为文本值。查询name字段或者address字段文本值为13的结果集。

    (7)query_string查询

    1 SearchResponse myresponse=responsebuilder.setQuery(                
    2                 //7.query_string查询 (所有字段内容包含以下文本的)
    3                 QueryBuilders.queryStringQuery("13")
    4                 )  
    5                 .setFrom(0).setSize(100)
    6 //                .setExplain(true)
    7                 .execute().actionGet(); 

    查询任意字段文本值为13的结果集。multi_match为指定某几个字段,query_string是查所有的字段。

    (8)simple_query_string查询

    1 SearchResponse myresponse=responsebuilder.setQuery(                
    2                 //8.simple_query_string查询
    3                 QueryBuilders.simpleQueryStringQuery("13")
    4                 )  
    5                 .setFrom(0).setSize(100)
    6 //                .setExplain(true)
    7                 .execute().actionGet(); 

    个人觉得与query_string没太大区别,感兴趣的可以深入研究

    (9)标识符查询

    这个没有研究,直接语法有兴趣的可以深入研究

    GetResponse getresponse = client.prepareGet("users", "user", "3").get();
    

    (10)前缀查询

    1 SearchResponse myresponse=responsebuilder.setQuery(                
    2                 //8.前缀查询 (一个汉字,字符小写)
    3 //                QueryBuilders.prefixQuery("name", "云")
    4                 QueryBuilders.prefixQuery("name", "12")
    5                 )  
    6                 .setFrom(0).setSize(100)
    7 //                .setExplain(true)
    8                 .execute().actionGet();  

    详情参考:ElasticSearch 常用的查询过滤语句

    (11)fuzzy_like_this,fuzzy_like_this_field,fuzzy查询

    SearchResponse myresponse=responsebuilder.setQuery(      
                    //9.fuzzy_like_this,fuzzy_like_this_field,fuzzy查询
                    //fuzzyQuery:使用模糊查询匹配文档查询
                    QueryBuilders.fuzzyQuery("name", "鹏16")
                    )  
                    .setFrom(0).setSize(100)
    //                .setExplain(true)
                    .execute().actionGet();  

    只发现了这个方法fuzzyQuery(String name, String value),也许高版本的会有其他方法

    (12)通配符查询

    wildcard查询和prefix查询类似,也是一个基于词条的低级别查询。但是它能够让你指定一个模式(Pattern),而不是一个前缀(Prefix)。它使用标准的shell通配符:?用来匹配任意字符,*用来匹配零个或者多个字符。

    1 SearchResponse myresponse=responsebuilder.setQuery(      
    2                 
    3                 //10.通配符查询 ?用来匹配任意字符,*用来匹配零个或者多个字符
    4 //                QueryBuilders.wildcardQuery("name", "岳*")
    5                 QueryBuilders.wildcardQuery("createTime", "?ue*")
    6                 )  
    7                 .setFrom(0).setSize(100)
    8 //                .setExplain(true)
    9                 .execute().actionGet();  

    有一点需要注意的是:由于?用来匹配字符的,而非字符串。查询中文的使用?是无效的。

    (13)more_like_this,more_like_this_field

        responsebuilder.setQuery(QueryBuilders.moreLikeThisQuery().addLikeText("long"))  
    
        responsebuilder.setQuery(QueryBuilders.moreLikeThisQuery("long"))  
    

     详情参考:http://blog.csdn.net/lu_wei_wei/article/details/51088125

    (14)rang查询

    range过滤允许我们按照指定范围查找一批数据

    范围操作符包含:

    • gt :: 大于
    • gte:: 大于等于
    • lt :: 小于
    • lte:: 小于等于
    1         SearchResponse myresponse=responsebuilder.setQuery(      
    2                 
    3                 //12.rang查询
    4                 QueryBuilders.rangeQuery("age").gt(10).lt(20)                
    5                 )  
    6                 .setFrom(0).setSize(100)
    7 //                .setExplain(true)
    8                 .execute().actionGet();  

    (15)dismax查询

     将子查询union 到一起,没个文档的分数是 子查询中相同文档的得分最大值。 
    例: 北京大饭店 酒索引得分 0; 店 得分 1; 大得分1.1 最后的结果是 北京大饭店相关度得分1.1   
        QueryBuilders.disMaxQuery()  
            .add(QueryBuilders.termQuery("hotelName","酒"))  
            .add(QueryBuilders.termQuery("hotelName","店"))  
            .add(QueryBuilders.termQuery("hotelName","大"));  
    
    
    

    (16)正则表达式查询

    1         SearchResponse myresponse=responsebuilder.setQuery(      
    2                 
    3                 //14.正则表达式查询                    
    4                 QueryBuilders.regexpQuery("createTime", "dec.*")                
    5                 )  
    6                 .setFrom(0).setSize(100)
    7 //                .setExplain(true)
    8                 .execute().actionGet(); 

    注意

    prefix,wildcard以及regexp查询基于词条进行操作。如果你在一个analyzed字段上使用了它们,它们会检查字段中的每个词条,而不是整个字段。

    比如,假设我们的title字段中含有"Quick brown fox",它会产生词条quick,brown和fox。

    这个查询能够匹配:

    { "regexp": { "title": "br.*" }}
    

    而不会匹配:

    { "regexp": { "title": "Qu.*" }} 
    { "regexp": { "title": "quick br*" }}
    
     Elasticsearch正则表达式语法: https://www.cnblogs.com/xing901022/p/6797597.html

    四、bool查询

    bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:

    • must :: 多个查询条件的完全匹配,相当于 and。
    • must_not :: 多个查询条件的相反匹配,相当于 not。
    • should :: 至少有一个查询条件匹配, 相当于 or。
     1  SearchResponse myresponse=responsebuilder.setQuery(      
     2                 
     3                 //15.bool查询                
     4                 QueryBuilders.boolQuery()
     5                 .must(QueryBuilders.multiMatchQuery("13", "name"))
     6                 .must(QueryBuilders.multiMatchQuery("13", "address"))            
     7                 )  
     8                 .setFrom(0).setSize(100)
     9 //                .setExplain(true)
    10                 .execute().actionGet();  

    multiMatchQuery(Object text, String... fieldNames)用法参考(6)multi_match查询

  • 相关阅读:
    浏览器漫谈
    无尽的烦恼
    微软的无聊
    作软件的人永远都是受气包吗?
    除非迫不得已不要用游标
    公司进行改革,路该如何走?
    Performance best practices for Web services
    HowTO: Create an Event Log Source in code, without the Permission errors
    Team Foundation Server安装指南
    百年不遇的,我遇到了两次
  • 原文地址:https://www.cnblogs.com/IT-study/p/7993453.html
Copyright © 2020-2023  润新知