Elasticsearch——查询//过滤详细总结

 

https://blog.csdn.net/donghaixiaolongwang/article/details/57418306

 

查询分为两种:字符串查询和DSL查询

1、字符串查询详细总结,此种方法一般用于简单测试。想要更加灵活,功能更加强大的查询功能还是得用DSL。但是这个字符串查询用起来还是挺方便的。切记不可将这种查询语句给你的客户。除非这个客户是你非常信任的。要不然这种语句会给你的集群带来致命的危险!!!!!

 

1>GET /index/tweet/_search?q=tweet:elasticsearch  #查询index索引 (相当于数据库)、tweet类型(相当于数据库中的表)、tweet字段中包含elasticsearch关键词的文章。

 

2>GET /index/tweet/_search?q=%2Bname%3Ajohn+%2Btweet%3Amary   #+name:john +tweet:mary  查询name字段包含john 同时tweet字段包含mary。%2B 是“+”,%3A是“:”

"+"前缀表示语句匹配条件必须被满足。类似的"-"前缀表示条件必须不被满足。所有条件如果没有+-表示是可选的——匹配越多,相关的文档就越多。

 

3>更复杂的例子:

 

  • name字段包含"mary""john"
  • date晚于2014-09-10
  • _all字段包含"aggregations""geo"

 

+name:(mary john) +date:>2014-09-10 +(aggregations geo)

 

编码后的查询字符串变得不太容易阅读:

GET /index/tweet/_search?q=%2Bname%3A(mary+john)+%2Bdate%3A%3E2014-09-10+%2B(aggregations+geo)

 

4>其他常用参数使用举

 

GET /index/tweet/_search?q=%2Bdate%3A%3E2014-09-10+%2Bname1%3A(A+B+C)+%2Dname2%3A(D+E+F)+name3%3A(G+H+I)&from=0&size=3 

##查询index索引tweet类型中date字段日期在2014-09-10以后,同时name1字段必须含有A或者B或者C中的一个,同时name2字段不能包含有D或者E或者F中的任意一个,
如果name3字段中包含了G或者H或者I那么他就会排在前边,包含的G、H、I、越多排名越靠前。并且只给我返回从0-3的3个结果。
 

附加:更加详细得字符串查询参数请参看:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/search-uri-request.html 

           “+”号“-”号和其他符号URL对照表参见:http://www.cnblogs.com/kobe8/p/4030396.html

 

 

 

##########################################################

##################################################################

2、DSL查询总结,此处才是主要的。一定要多看几遍并且尽量用项目来练习,不然不能灵活使用。多看查询和过滤的语句,较常用。

英文好的参看官方DSL语句。参看网址(权威):https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-match-query.html

偷懒的看下边:个人的使用经验,和参考别人的。仅供参考

 

 

下边内容多摘自网站(下方列出了较常用的查询语句,其他更为专有的查询语句请自行查询。):https://es.xiaoleilu.com/080_Structured_Search/10_compoundfilters.html

最重要的查询过滤语句

 

term 过滤

 

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

  1.  
    { "term": { "age": 26 }}
  2.  
    { "term": { "date": "2014-09-01" }}
  3.  
    { "term": { "public": true }}
  4.  
    { "term": { "tag": "full_text" }}
例子:注意我用的是ik分词器。你最好先用英文来搞。查一个单词

GET /ik2_index/ik_type6/_search
{
  "query": {
    "term": {
      "content1": "AAA"
    }
  }
}

 

 

terms 过滤

 

terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配:

+
  1.  
    {
  2.  
    "terms": {
  3.  
    "tag": [ "search", "full_text", "nosql" ]
  4.  
    }
  5.  
    }
例子:注意我用的是ik分词器。你最好先用英文来搞。查一个单词

GET /ik2_index/ik_type6/_search
{
  "query": {
    "terms": {
        "content1": [ "AAA", "BBB", "美国" ]
        }
  }
}

 

 

range 过滤

 

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

  1.  
    {
  2.  
    "range": {
  3.  
    "age": {
  4.  
    "gte": 20,
  5.  
    "lt": 30
  6.  
    }
  7.  
    }
  8.  
    }
例子:

GET /ik2_index/ik_type6/_search
{
  "query": {
    "range": {
        "age": {
            "gte":  20,
            "lt":   30
        }
    }
  }
}

 

围操作符包含:

gt :: 大于

gte:: 大于等于

lt :: 小于

lte:: 小于等于

 

 

bool 过滤

 

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

must :: 多个查询条件的完全匹配,相当于 and

must_not :: 多个查询条件的相反匹配,相当于 not

should :: 至少有一个查询条件匹配, 相当于 or

这些参数可以分别继承一个过滤条件或者一个过滤条件的数组:还可以继续嵌套

  1.  
    {
  2.  
    "bool": {
  3.  
    "must": { "term": { "folder": "inbox" }},
  4.  
    "must_not": { "term": { "tag": "spam" }},
  5.  
    "should": [
  6.  
    { "term": { "starred": true }},
  7.  
    { "term": { "unread": true }}
  8.  
    ]
  9.  
    }
  10.  
    }

例子:

GET /ik2_index/ik_type6/_search
{
  "query": {
    "bool": {
      "must": {
        "term": {
          "folder": "inbox"
        }
      },
      "must_not": {
        "term": {
          "tag": "spam"
        }
      },
      "should": [
        {
          "term": {
            "starred": true
          }
        },
        {
          "term": {
            "unread": true
          }
        }
      ]
    }
  }
}

 

附加:更多过滤参看网址:https://segmentfault.com/a/1190000004429689

 

 

 

match 查询

 

match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。

如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析match一下查询字符:

  1.  
    {
  2.  
    "match": {
  3.  
    "tweet": "About Search"
  4.  
    }
  5.  
    }

如果用match下指定了一个确切值,在遇到数字,日期,布尔值或者not_analyzed 的字符串时,它将为你搜索你给定的值:

  1.  
    { "match": { "age": 26 }}
  2.  
    { "match": { "date": "2014-09-01" }}
  3.  
    { "match": { "public": true }}
  4.  
    { "match": { "tag": "full_text" }}

提示: 做精确匹配搜索时,你最好用过滤语句,因为过滤语句可以缓存数据。

不像我们在《简单搜索》中介绍的字符查询,match查询不可以用类似"+usid:2 +tweet:search"这样的语句。 它只能就指定某个确切字段某个确切的值进行搜索,而你要做的就是为它指定正确的字段名以避免语法错误。

例子1:

GET /ik2_index/ik_type6/_search
{
  "query": {
     "match": {
            "age": 26
          }
  }
}

例子2:多个match可以连在一起来搞,挺爽吧。里边得内容必须全部成立。当然你可以放到must_not(都不能成立)或者should(能成立的排在前边)中GET /ik2_index/ik_type6/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "age": 26
          }
        },
        {
          "match": {
            "date": "2014-09-01"
          }
        },
        {
          "match": {
            "public": true
          }
        },
        {
          "match": {
            "tag": "full_text"
          }
        }
      ]
    }
  }
}

 

#在没有must句子时,should句子中至少有一个成立。所以现在是或的关系

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "War and Peace"
          }
        },
        {
          "match": {
            "author": "Leo Tolstoy"
          }
        }
      ]
    }
  }
}

 

 

例子3:GET /my_index/my_type/_search
{
  "query": {
    "match": {
      "title": "BROWN DOG!"
    }
  }
}

 

 

match 查询提高精度

 

匹配包含任意个数查询关键字的文档可能会得到一些看似不相关的结果,这是一种霰弹策略(shotgun approach)。然而我们可能想得到包含所有查询关键字的文档。换句话说,我们想得到的是匹配'brown AND dog'的文档,而非'brown OR dog'

match查询接受一个'operator'参数,默认值为or。如果要求所有查询关键字都匹配,可以更改参数值为and

  1.  
    GET /my_index/my_type/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "match": {
  5.  
    "title": { <1>
  6.  
    "query": "BROWN DOG!",
  7.  
    "operator": "and"
  8.  
    }
  9.  
    }
  10.  
    }
  11.  
    }

 



match 查询控制精度(莫要小看此处,可用于相似文章判断查询)

在 all 和 any 之间的选择有点过于非黑即白。如果用户指定了5个查询关键字,而一个文档只包含了其中的4个?将'operator'设置为'and'会排除这个文档。

有时这的确是用户想要的结果。但在大多数全文检索的使用场景下,用户想得到相关的文档,排除那些不太可能相关的文档。换句话说,我们需要介于二者之间的选项。

match查询有'minimum_should_match'参数,参数值表示被视为相关的文档必须匹配的关键词个数。参数值可以设为整数,也可以设置为百分数。因为不能提前确定用户输入的查询关键词个数,使用百分数也很合理。

  1.  
    GET /my_index/my_type/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "match": {
  5.  
    "title": {
  6.  
    "query": "quick brown dog",
  7.  
    "minimum_should_match": "75%"
  8.  
    }
  9.  
    }
  10.  
    }
  11.  
    }

'minimum_should_match'被设置为百分数时,查询进行如下:在上面的例子里,'75%'会被下舍为'66.6%',也就是2个关键词。不论参数值为多少,进入结果集的文档至少应匹配一个关键词。


 


短语匹配(Phrase Matching) ##match_phrase查询。比较有用。用到match的地方都可能用到。

这个查询流程是:先将查询内容按照查询字段的分词器进行分词,之后所有分词结果,必须都在该字段中能查到的文章才算合格的。 GET /my_index/my_type/_search { "query": { "match_phrase": { "title": "quick brown fox" } } }

 

match_phrase查询优化

GET ik2_index/ik_type8/_search
{
  "query": {
    "match_phrase": {
      "content2": {
      "query": "quick fox",
      "slop": 2
      }
      
      
    }
  }
}

注释:slop参数可以给match_phrase一些自由度。slop解释参看https://www.elastic.co/guide/en/elasticsearch/guide/current/slop.html

 

 

短语匹配之前缀查询(match_phrase_prefix)查询期间的即时搜索(Query-time Search-as-you-type)

 

 

此查询和match_phrase查询的工作方式基本相同,除了它会将查询字符串中的最后一个单词当做一个前缀。换言之,前面的例子会查找以下内容:

  • johnnie
  • 紧接着的是walker
  • 紧接着的是以bl开头的单词

max_expansions参数会控制能够匹配该前缀的词条的数量。它会找到首个以bl开头的词条然后开始收集(以字母表顺序)直到所有以bl开头的词条都被遍历了或者得到了比max_expansions数量多1的时候才会结束(相同的词条算一个)。这个参数在生产环境一定要限制,否则不会有好的体验。不要忘了在用户每敲入一个字符的时候,该查询就要被执行一次,因此它的速度需要快。如果第一个结果集不符合用户的期望,那么他们就会继续输入直到得到他们需要的结果。

 

GET ik2_index/ik_type8/_search
{
  "query": {
    "match_phrase_prefix": {
      "content2": {
      "query": "johnnie walker bl",
      "max_expansions": 5
      }
      
      
    }
  }
}

 

 

prefix查询,查找某个字段中所有分词,只要有分词项是以yell开头的。那这个文档就是符合我们要求的。

GET ik2_index/ik_type8/_search
{
  "query": {
    "prefix": {
      "content2": "yell"     
    }
  }
}

 

 

 

 

multi_match 查询

 

multi_match查询允许你做match查询的基础上同时搜索多个字段:

  1.  
    {
  2.  
    "multi_match": {
  3.  
    "query": "full text search",
  4.  
    "fields": [ "title", "body" ]
  5.  
    }
  6.  
    }

例子:同时在一个字段中搜索多个term关键词,关键词之间是或的关系字段之间也是或得关系。

GET /ik2_index/ik_type6/_search
{
  "query": {
    "multi_match": {
      "query": "full text search",
      "fields": [
        "title",
        "body"
      ]
    }
  }
}

 

 

更加精细得multi_match 查询解释

 

multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询。

提示:存在几种类型的multi_match查询:best_fields,most_fields以及cross_fields。

默认情况下,该查询以best_fields类型执行,它会为每个字段生成一个match查询,然后将这些查询包含在一个dis_max查询中。下面的dis_max查询:

  1.  
    {
  2.  
    "dis_max": {
  3.  
    "queries": [
  4.  
    {
  5.  
    "match": {
  6.  
    "title": {
  7.  
    "query": "Quick brown fox",
  8.  
    "minimum_should_match": "30%"
  9.  
    }
  10.  
    }
  11.  
    },
  12.  
    {
  13.  
    "match": {
  14.  
    "body": {
  15.  
    "query": "Quick brown fox",
  16.  
    "minimum_should_match": "30%"
  17.  
    }
  18.  
    }
  19.  
    },
  20.  
    ],
  21.  
    "tie_breaker": 0.3
  22.  
    }
  23.  
    }

可以通过multi_match简单地重写如下:

  1.  
    {
  2.  
    "multi_match": {
  3.  
    "query": "Quick brown fox",
  4.  
    "type": "best_fields", <1>
  5.  
    "fields": [ "title", "body" ],
  6.  
    "tie_breaker": 0.3,
  7.  
    "minimum_should_match": "30%" <2>
  8.  
    }
  9.  
    }
  10.  
     

<1> 注意到以上的type属性为best_fields。

<2> minimum_should_match和operator参数会被传入到生成的match查询中。

 

在字段名中使用通配符:

字段名可以通过通配符指定:任何匹配了通配符的字段都会被包含在搜索中。你可以通过下面的查询来匹配book_title,chapter_title以及section_title字段:

  1.  
    {
  2.  
    "multi_match": {
  3.  
    "query": "Quick brown fox",
  4.  
    "fields": "*_title"
  5.  
    }
  6.  
    }

加权个别字段:

个别字段可以通过caret语法(^)进行加权:仅需要在字段名后添加^boost,其中的boost是一个浮点数:

  1.  
    {
  2.  
    "multi_match": {
  3.  
    "query": "Quick brown fox",
  4.  
    "fields": [ "*_title", "chapter_title^2" ] <1>
  5.  
    }
  6.  
    }

<1> chapter_title字段的boost值为2,而book_title和section_title字段的boost值为默认的1。


 

 

 

 

 

 

 

bool 查询

 

bool 查询与 bool 过滤相似,用于合并多个查询子句。不同的是,bool 过滤可以直接给出是否匹配成功, 而bool 查询要计算每一个查询子句的_score (相关性分值)。

must:: 查询指定文档一定要被包含。

must_not:: 查询指定文档一定不要被包含。

should:: 查询指定文档,有则可以为文档相关性加分。

以下查询将会找到 title 字段中包含 "how to make millions",并且 "tag" 字段没有被标为spam。 如果有标识为 "starred" 或者发布日期为2014年之前,那么这些匹配的文档将比同类网站等级高:

  1.  
    {
  2.  
    "bool": {
  3.  
    "must": { "match": { "title": "how to make millions" }},
  4.  
    "must_not": { "match": { "tag": "spam" }},
  5.  
    "should": [
  6.  
    { "match": { "tag": "starred" }},
  7.  
    { "range": { "date": { "gte": "2014-01-01" }}}
  8.  
    ]
  9.  
    }
  10.  
    }

例子:

GET /ik2_index/ik_type6/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "title": "how to make millions"
        }
      },
      "must_not": {
        "match": {
          "tag": "spam"
        }
      },
      "should": [
        {
          "match": {
            "tag": "starred"
          }
        },
        {
          "range": {
            "date": {
              "gte": "2014-01-01"
            }
          }
        }
      ]
    }
  }
}

 

 

bool 查询精度控制

 

所有的 must 子句必须匹配, 并且所有的 must_not 子句必须不匹配, 但是多少should 子句应该匹配呢? 默认的,不需要匹配任何should 子句,一种情况例外:如果没有must子句,就必须至少匹配一个should子句。

像我们控制match查询的精度一样,我们也可以通过minimum_should_match参数控制多少should子句需要被匹配,这个参数可以是正整数,也可以是百分比。

  1.  
    GET /my_index/my_type/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "bool": {
  5.  
    "should": [
  6.  
    { "match": { "title": "brown" }},
  7.  
    { "match": { "title": "fox" }},
  8.  
    { "match": { "title": "dog" }}
  9.  
    ],
  10.  
    "minimum_should_match": 2 <1>
  11.  
    }
  12.  
    }
  13.  
    }

<1> 这也可以用百分比表示

 

bool 查询精度控制——提高查询得分

 

 

我们可以在任何查询子句中指定一个boost值来控制相对权重,默认值为1。一个大于1的boost值可以提高查询子句的相对权重。因此我们的查询:

  1.  
    GET /_search
  2.  
    {
  3.  
    "query": {
  4.  
    "bool": {
  5.  
    "must": {
  6.  
    "match": { (1)
  7.  
    "content": {
  8.  
    "query": "full text search",
  9.  
    "operator": "and"
  10.  
    }
  11.  
    }
  12.  
    },
  13.  
    "should": [
  14.  
    { "match": {
  15.  
    "content": {
  16.  
    "query": "Elasticsearch",
  17.  
    "boost": 3 (2)
  18.  
    }
  19.  
    }},
  20.  
    { "match": {
  21.  
    "content": {
  22.  
    "query": "Lucene",
  23.  
    "boost": 2 (3)
  24.  
    }
  25.  
    }}
  26.  
    ]
  27.  
    }
  28.  
    }
  29.  
    }
  1. 这些查询子句的boost值为默认值1
  2. 这个子句是最重要的,因为他有最高的boost值。
  3. 这个子句比第一个查询子句的要重要,但是没有“Elasticsearch”子句重要。

注意:

  1. boost参数用于提高子句的相对权重(boost值大于1)或者降低子句的相对权重(boost值在0-1之间),但是提高和降低并非是线性的。换句话说,boost值为2并不能够使结果变成两部的得分。

  2. 另外,boost值被使用了以后新的得分是标准的。每个查询类型都会有一个独有的标准算法,算法的详细内容并不在本书的范畴。简单的概括一下,一个更大的boost值可以得到一个更高的得分。

  3. 如果你自己实现了没有基于TF/IDF的得分模型,但是你想得到更多的对于提高得分过程的控制,你可以使用function_score查询来调整一个文档的boost值而不用通过标准的步骤。

 

 

 

 

 

 

最佳字段查询###dis_max查询

 

我们可以使用dis_max查询(Disjuction Max Query)。


这种查询方式可以使你的查询结果更加精准,体现在:某一个字段同时包含Brown fox两个词,将会比两个字段各自包含Brown fox中的任意一个词得分高。这样可以使查询结果更加精准。这主要原因还在与查询中的分数计算方法。相关性分数的计算方法参见:https://es.xiaoleilu.com/056_Sorting/90_What_is_relevance.html

  1.  
    {
  2.  
    "query": {
  3.  
    "dis_max": {
  4.  
    "queries": [
  5.  
    { "match": { "title": "Brown fox" }},
  6.  
    { "match": { "body": "Brown fox" }}
  7.  
    ]
  8.  
    }
  9.  
    }
  10.  
    }

注释:为什么上边得dis_max查询会得到更相关的结果。如果你不是用上边的得语句而用下边的这个,就会看到两个字段各自包含一个词,会比一个字段同时包含两个词得分高。显然上边得查询准确性更相关。注意使用的场景,遇见了在用这种查询。

 

bool查询是如何计算得到其分值的:

  • 1.运行should子句中的两个查询
  • 2.相加查询返回的分值
  • 3.将相加得到的分值乘以匹配的查询子句的数量
  • 4.除以总的查询子句的数量

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "Brown fox"
          }
        },
        {
          "match": {
            "body": "Brown fox"
          }
        }
      ]
    }
  }
}

 

最佳字段查询###dis_max查询#####最佳字段查询的调优

 

 

tie_breaker  这意味着另一个字段在计算得分时将不会被完全丢弃而是有所保留

 

但是,将其它匹配的查询子句考虑进来也是可能的。通过指定tie_breaker参数:

  1.  
    {
  2.  
    "query": {
  3.  
    "dis_max": {
  4.  
    "queries": [
  5.  
    { "match": { "title": "Quick pets" }},
  6.  
    { "match": { "body": "Quick pets" }}
  7.  
    ],
  8.  
    "tie_breaker": 0.3
  9.  
    }
  10.  
    }
  11.  
    }

tie_breaker参数会让dis_max查询的行为更像是dis_max和bool的一种折中。它会通过下面的方式改变分值计算过程:

  • 1.取得最佳匹配查询子句的_score。
  • 2.将其它每个匹配的子句的分值乘以tie_breaker。
  • 3.将以上得到的分值进行累加并规范化。

通过tie_breaker参数,所有匹配的子句都会起作用,只不过最佳匹配子句的作用更大。

提示:tie_breaker的取值范围是0到1之间的浮点数,取0时即为仅使用最佳匹配子句(译注:和不使用tie_breaker参数的dis_max查询效果相同),取1则会将所有匹配的子句一视同仁。它的确切值需要根据你的数据和查询进行调整,但是一个合理的值会靠近0,(比如,0.1 -0.4),来确保不会压倒dis_max查询具有的最佳匹配性质。

最多字段查询

  1.  
    GET /my_index/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "multi_match": {
  5.  
    "query": "jumping rabbits",
  6.  
    "type": "most_fields", <1>
  7.  
    "fields": [ "title", "title.std" ]
  8.  
    }
  9.  
    }
  10.  
    }
  11.  
     

<1> 在上述查询中,由于我们想合并所有匹配字段的分值,因此使用的类型为most_fields。这会让multi_match查询将针对两个字段的查询子句包含在一个bool查询中,而不是包含在一个dis_max查询中


注释:和下边得语句一样

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "Brown fox"
          }
        },
        {
          "match": {
            "body": "Brown fox"
          }
        }
      ]
    }
  }
}

 

 

最多字段查询调优

 

 

个字段对最终分值的贡献可以通过指定boost值进行控制。比如,我们可以提升title字段来让该字段更加重要,这也减小了其它信号字段的影响:

  1.  
    GET /my_index/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "multi_match": {
  5.  
    "query": "jumping rabbits",
  6.  
    "type": "most_fields",
  7.  
    "fields": [ "title^10", "title.std" ] <1>
  8.  
    }
  9.  
    }
  10.  
    }

<1> boost=10让title字段的相关性比title.std更重要。 计分的时候会多给title分量。

 

使用most_fields存在的问题

使用most_fields方法执行实体查询有一些不那么明显的问题:

  • 它被设计用来找到匹配任意单词的多数字段,而不是找到跨越所有字段的最匹配的单词。这将会引申出跨字段查询方式。
  • 它不能使用operator或者minimum_should_match参数来减少低相关度结果带来的长尾效应。这个没辙
  • 每个字段的词条频度是不同的,会互相干扰最终得到较差的排序结果。多个字段值可以放到同一个字段中,这样可以解决词条频度不均衡而计分不准确得问题。
  • 自定义_all字段

    元数据:_all字段中,我们解释了特殊的_all字段会将其它所有字段中的值作为一个大字符串进行索引。尽管将所有字段的值作为一个字段进行索引并不是非常灵活。如果有一个自定义的_all字段用来索引人名,另外一个自定义的_all字段用来索引地址就更好了。

    ES通过字段映射中的copy_to参数向我们提供了这一功能:

    1.  
      PUT /my_index
    2.  
      {
    3.  
      "mappings": {
    4.  
      "person": {
    5.  
      "properties": {
    6.  
      "first_name": {
    7.  
      "type": "string",
    8.  
      "copy_to": "full_name" <1>
    9.  
      },
    10.  
      "last_name": {
    11.  
      "type": "string",
    12.  
      "copy_to": "full_name" <1>
    13.  
      },
    14.  
      "full_name": {
    15.  
      "type": "string"
    16.  
      }
    17.  
      }
    18.  
      }
    19.  
      }
    20.  
      }

    <1> first_name和last_name字段中的值会被拷贝到full_name字段中。

    有了这个映射,我们可以通过first_name字段查询名字,last_name字段查询姓氏,或者full_name字段查询姓氏和名字。

    提示:first_name和last_name字段的映射和full_name字段的索引方式的无关。full_name字段会从其它两个字段中拷贝字符串的值,然后仅根据full_name字段自身的映射进行索引。

解释参看:知道看不明白所以给出了链接,我看了好几遍才前后贯穿上。差点对不上号。https://es.xiaoleilu.com/110_Multi_Field_Search/40_Field_centric.html

 

 

跨字段查询

GET /_validate/query?explain            #词条peter必须出现在任一字段中,同时词条smith也必须出现在任一字段中。这就是以词条为中心和字段为中心得差别。解决了1、找到匹配任意单词的多数字段,还是找到跨越所有字段的最匹配的单词.2、查询结果得长尾效应解决了。
{
    "query": {
        "multi_match": {
            "query":       "peter smith",
            "type":        "cross_fields",
            "operator":    "and",
            "fields":      [ "first_name", "last_name" ]
        }
    }
}

 

cross_fields类型采用了一种以词条为中心(Term-centric)的方法,这种方法和best_fields及most_fields采用的以字段为中心(Field-centric)的方法有很大的区别。它将所有的字段视为一个大的字段,然后在任一字段中搜索每个词条。可以把所有字段认为是一个字段,在里边进行查询。解决了3、词条分布不均匀对得分得影响。


注意:这种查询方式解决了most_fields查询的所有3个问题。

 

跨字段查询调优

对于first_name和last_name这类拥有近似值的字段,也许加权是不必要的,但是如果你通过title和description字段来搜索书籍,那么你或许会给予title字段更多的权重。这可以通过前面介绍的caret(^)语法来完成:

 

GET /books/_search
{
  "query": {
    "multi_match": {
      "query": "peter smith",
      "type": "cross_fields",
      "fields": [
        "title^2",
        "description"
      ]
    }
  }
}

 

 

 

 

fuzzy查询。当用户输入错误单词‘cirme’,能返回正确的单词‘crime’

 

GET ik2_index/ik_type8/_search
{
  "query": {
    "fuzzy": {
      "content2": {
        "value":"quick",
        "min_similarity":1,
        "max_expansions":5
        
      }
      
    }
  }
 
}

value:要查询的词项。

min_similarity:默认值1,值越大需要的相似越小。

max_expansions::默认值全部。只给我返回相似的前max_expansions+1条(词条一样的算一条)。

 

 

Wildcard查询,和sql的like有点相似。这个挺好用的。可以临时查数据。

GET ik2_index/ik_type8/_search
{
  "query": {
    "wildcard": {
    "content2":"qui?k"
      
    
    }
  }
 
}

 

more_like_this查询

GET ik2_index/ik_type8/_search
{ "from":0,
"size":3,
  "query": {
    "more_like_this": {
    "fields":["content2"],
    "like_text":"quick  fox",
    "min_term_freq": 1,
    "min_doc_freq": 1
         
    }
  }
 
}

注释:和match_phrase_prefix相似,但是比它更灵活。这个语句能查出类似quick yellow fox   、quick black fox。相当于吧fuzzy语句用or连接起来。

其他参数保持不变。min_term_freq 指明文档中词项出现的最低频率,低于该值的词项将被省略(测试没有作用)。min_dox_freq指明词项必须出现在至少多少个文档中才不被s省略(测试有作用)。max_query_terms指明生成的查询中查询词项的最大数目,超过这个数目的词项将被省略。默认为25(查询的字符串很长时可能有用)

 

查询与过滤条件的合并

1>、带过滤的查询语句,这种过滤属于前置过滤——先过滤在查询

GET /_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "email": "business opportunity"
        }
      },
      "filter": {
        "term": {
          "folder": "inbox"
        }
      }
    }
  }
}

//多次过滤可参看

GET /_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "content3": "德国"
        }
      },
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "content3": "德国"
              }
            },
            {
              "term": {
                "content2": "美国"
              }
            },
            {
              "term": {
                "content1": "AAA"
              }
            }
          ]
        }
      }
    }
  }
}

//先过滤、在查询、再过滤、在查询

GET ik2_index/ik_type6/_search
{
  "query": {
    "filtered": {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "content3": "德国"
              }
            },
            {
              "match": {
                "content3": "泰国"
              }
            }
          ]
        }
      },
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "content2": "日本"
              }
            },
            {
              "term": {
                "content2": "美国"
              }
            }
          ]
        }
      }
    }
  },
  "post_filter": {
    "bool": {
      "must": [
        {
          "term": {
            "content2": "日本"
          }
        },
        {
          "term": {
            "content2": "美国"
          }
        },
        {
          "match": {
            "content1": "AAA"
          }
        },
        {
          "match": {
            "content3": "DDD"
          }
        }
      ]
    }
  }
}



 

2>、这种属于后置过滤器

GET ik2_index/ik_type6/_search
{
  "query": {
    "match": {
      "content3": "AAA"
    }
  },
  "post_filter": {
    "term": {
          "content3": "AAA"
        }
  }
}

 

//多次过滤

GET ik2_index/ik_type6/_search
{
  "query": {
    "match": {
      "content3": "BBB"
    }
  },
  "post_filter": {
    "bool": {
      "must": [
        {
          "term": {
            "content3": "德国"
          }
        },
        {
          "term": {
            "content2": "美国"
          }
        },
        {
          "term": {
            "content1": "AAA"
          }
        }
      ]
    }
  }
}

//先查询、再过滤、再查询

GET ik2_index/ik_type6/_search
{
 
 
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content3": "德国"
          }
        },
        {
          "match": {
            "content3": "泰国"
          }
        }
      ]
    }
  },
  "post_filter": {
    "bool": {
       "must": [
            {
              "term": {
                "content2": "日本"
              }
            },
            {
              "term": {
                "content2": "美国"
              }
            },
             {
              "match": {
                "content1": "GGG"
              }
            },
            {
              "match": {
                "content3": "AAA"
              }
            }
          ]
    }
  }
}

 

 

 

 

其他可能有用的查询:

 

检索文档是否存在

如果你想做的只是检查文档是否存在——你对内容完全不感兴趣——使用HEAD方法来代替GETHEAD请求不会返回响应体,只有HTTP头:

curl -i -XHEAD http://localhost:9200/website/blog/123

Elasticsearch将会返回200 OK状态如果你的文档存在:

  1.  
    HTTP/1.1 200 OK
  2.  
    Content-Type: text/plain; charset=UTF-8
  3.  
    Content-Length: 0

如果不存在返回404 Not Found

curl -i -XHEAD http://localhost:9200/website/blog/124
  1.  
    HTTP/1.1 404 Not Found
  2.  
    Content-Type: text/plain; charset=UTF-8
  3.  
    Content-Length: 0

当然,这只表示你在查询的那一刻文档不存在,但并不表示几毫秒后依旧不存在。另一个进程在这期间可能创建新文档。

 

一次检索多个文档

POST /_mget
{
   "docs" : [
      {
         "_index" : "website",
         "_type" :  "blog",
         "_id" :    2
      },
      {
         "_index" : "website",
         "_type" :  "pageviews",
         "_id" :    1,
         "_source": "views"
      }
   ]

 

附加:本文内容多摘自网站:可自行学习。毕竟总结不全。这篇主要总结了查询。时间不早了,模糊查询后边补上。https://es.xiaoleilu.com/030_Data/20_Exists.html

 

posted @ 2020-02-17 14:17  kelelipeng  阅读(3724)  评论(0编辑  收藏  举报