Elasticsearch学习笔记之(四)搜索详解

目录

搜索API

搜索API 端点地址

URI Search

查询结果说明

特殊的查询参数用法

Request  body Search

query 元素定义查询

指定返回哪些内容

Script Field 用脚本来对命中的每个文档的字段进行运算后返回

过滤

sort  排序

sort

折叠

分页

高亮  

Profile  为了调试、优化  

count  api

validate api  

Explain api  

Search Shards API

Search Template

Query DSL

DSL是什么?

Query and filter context

Query and filter context

Match all query

Full text querys

match query

match query  示例

match  phrase  query

match  phrase  prefix query

Multi match  query

Common terms query

tf-idf 相关性计算模型简介

Common terms query

Query string query

查询描述规则语法(查询解析语法):

Simple Query string query

Term level querys

Term query

Terms query  嵌套查询示例

range query

range query

exists  query

prefix  query   词项前缀查询

wildcard  query   通配符查询:  ?  *

regexp query   正则查询

fuzzy query   模糊查询

type query   mapping type 查询

ids query   根据文档id查询

Compound querys 复合查询

Constant Score query

Bool query


搜索API

Elasticsearch学习笔记之(四)搜索详解_第1张图片

搜索API 端点地址

GET /twitter/_search?q=user:kimchy
GET /twitter/tweet,user/_search?q=user:kimchy
GET /kimchy,elasticsearch/_search?q=tag:wow
GET /_all/_search?q=tag:wow
GET /_search?q=tag:wow

搜索的端点地址可以是多索引多mapping type的。搜索的参数可作为URI请求参数给出,也可用 request body 给出。

URI Search

URI 搜索方式通过URI参数来指定查询相关参数。让我们可以快速做一个查询。

GET /twitter/_search?q=user:kimchy

可用的参数请参考: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html

查询结果说明

{
    "took": 1,            //耗时(毫秒)
    "timed_out": false,   //是否超时
    "_shards":{           //查询了多少个分片
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
    },
    "hits":{                    //命中结果
        "total" : 1,            //总命中数
        "max_score": 1.3862944,  //最高得分
        "hits" : [               //本页结果文档数组
            {
                "_index" : "twitter", //文档
                "_type" : "_doc",
                "_id" : "0",
                "_score": 1.3862944,
                "_source" : {
                    "user" : "kimchy",
                    "message": "trying out Elasticsearch",
                    "date" : "2009-11-15T14:12:12",
                    "likes" : 0
                }            }        ]    }}

特殊的查询参数用法

如果我们只想知道有多少文档匹配某个查询,可以这样用参数:

GET /bank/_search?q=city:b*&size=0

如果我们只想知道有没有文档匹配某个查询,可以这样用参数:

GET /bank/_search?q=city:b*&size=0&terminate_after=1

比较两个查询的结果,有什么区别。

Request  body Search

Request body 搜索方式以JSON格式在请求体中定义查询 query。请求方式可以是 GET 、POST 。

GET /twitter/_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

可用的参数:

  • timeout:请求超时时长,限定在指定时长内响应(即使没查完);
  • from: 分页的起始行,默认0;
  • size:分页大小;
  • request_cache:是否缓存请求结果,默认true。
  • terminate_after:限定每个分片取几个文档。如果设置,则响应将有一个布尔型字段terminated_early来指示查询执行是否实际已经terminate_early。缺省为no terminate_after;
  • search_type:查询的执行方式,可选值dfs_query_then_fetch or query_then_fetch ,默认: query_then_fetch ;
  • batched_reduce_size:一次在协调节点上应该减少的分片结果的数量。如果请求中的潜在分片数量可能很大,则应将此值用作保护机制以减少每个搜索请求的内存开销。

query 元素定义查询

query 元素用Query DSL 来定义查询。

GET /_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

指定返回哪些内容

  •  source filter  对_source字段进行选择
GET /_search
{
    "_source": false,
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}
GET /_search
{
    "_source": [ "obj1.*", "obj2.*" ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}
GET /_search
{
    "_source": "obj.*",
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}
GET /_search
{
    "_source": {
        "includes": [ "obj1.*", "obj2.*" ],
        "excludes": [ "*.description" ]
    },
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}
  •   stored_fields    来指定返回哪些stored字段
GET /_search
{
    "stored_fields" : ["user", "postDate"],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}



* 可用来指定返回所有存储字段
  •   docValue Field    返回存储了docValue的字段值
GET /_search
{
    "query" : {
        "match_all": {}
    },
    "docvalue_fields" : ["test1", "test2"]
}
  •   version    来指定返回文档的版本字段
GET /_search
{
    "version": true,
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}
  •   explain 返回文档的评分解释
GET /_search
{
    "explain": true,
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

Script Field 用脚本来对命中的每个文档的字段进行运算后返回

GET /bank/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "test1": {
      "script": {
        "lang": "painless",
        "source": "doc['balance'].value * 2"
      }
    },
    "test2": {
      "script": {
        "lang": "painless",
        "source": "doc['age'].value * params.factor",
        "params": {
          "factor": 2
        }
      }
    } }}

//doc指文档
GET /bank/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "ffx": {
      "script": {
        "lang": "painless",
        "source": "doc['age'].value * doc['balance'].value"
      }
    },
    "balance*2": {
      "script": {
        "lang": "painless",
        "source": "params['_source'].balance*2"
      }
    }
  }
}

//params  _source 取 _source字段值
//官方推荐使用doc,理由是用doc效率比取_source 高。

过滤

min_score  限制最低评分得分。

GET /_search
{
    "min_score": 0.5,
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}
  • post_filter  后置过滤:在查询命中文档、完成聚合后,再对命中的文档进行过滤。

如:要在一次查询中查询品牌为gucci且颜色为红色的shirts,同时还要得到gucci品牌各颜色的shirts的分面统计。

PUT /shirts
{
    "mappings": {
        "_doc": {
            "properties": {
                "brand": { "type": "keyword"},
                "color": { "type": "keyword"},
                "model": { "type": "keyword"}
            }
        }
    }
}
PUT /shirts/_doc/1?refresh
{
    "brand": "gucci",
    "color": "red",
    "model": "slim"
}
PUT /shirts/_doc/2?refresh
{
    "brand": "gucci",
    "color": "green",
    "model": "seec"
}
GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": { "brand": "gucci" } 
      }
    }
  },
  "aggs": {
    "colors": {
      "terms": { "field": "color" } 
    }
  },
  "post_filter": { 
    "term": { "color": "red" }
  }
}

sort  排序

可以指定按一个或多个字段排序。也可通过_score指定按评分值排序,_doc 按索引顺序排序。默认是按相关性评分从高到低排序。

GET /bank/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }    },
    {
      "balance": {
        "order": "asc"
      }    },
    "_score"
  ]
}
//order 值:asc、desc。如果不给定,默认是asc,_score默认是desc
 "hits": {
    "total": 1000,
    "max_score": null,
    "hits": [
      {
        "_index": "bank",
        "_type": "_doc",
        "_id": "549",
        "_score": 1,
        "_source": {
          "account_number": 549,
          "balance": 1932, "age": 40, "state": "OR"
        },
        "sort": [
          40,
          1932,
          1
        ]    }

//结果中每个文档会有排序字段值给出
  • 多值字段排序

对于值是数组或多值的字段,也可进行排序,通过mode参数指定按多值的:

min 

最小值

max 

最大值

sum 

avg 

平均

median 

中值

 

PUT /my_index/_doc/1?refresh
{
   "product": "chocolate",
   "price": [20, 4]
}

POST /_search
{
   "query" : {
      "term" : { "product" : "chocolate" }
   },
   "sort" : [
      {"price" : {"order" : "asc", "mode" : "avg"}}
   ]
}
  • Missing values  缺失该字段的文档

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#geo-sorting

GET /_search
{
    "sort" : [
        { "price" : {"missing" : "_last"} }
    ],
    "query" : {
        "term" : { "product" : "chocolate" }
    }
}
//missing 的值可以是 _last, _first 
  • 地理空间距离排序
    • _geo_distance   距离排序关键字
    • pin.location是 geo_point 类型的字段
    • distance_type:距离计算方式 arc球面 、plane 平面。
    • unit: 距离单位 km 、m   默认m
GET /_search
{
    "sort" : [
        {
            "_geo_distance" : {
                "pin.location" : [-70, 40],
                "order" : "asc",
                "unit" : "km",
                "mode" : "min",
                "distance_type" : "arc"
            }
        }
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

sort

Script Based Sorting   基于脚本计算的排序  

GET /_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    },
    "sort" : {
        "_script" : {
            "type" : "number",
            "script" : {
                "lang": "painless",
                "source": "doc['field_name'].value * params.factor",
                "params" : {
                    "factor" : 1.1
                }
            },
            "order" : "asc"
        }
    }
}

折叠

用 collapse指定根据某个字段对命中结果进行折叠

GET /bank/_search
{
    "query": {
        "match_all": {}
    },
    "collapse" : {
        "field" : "age" 
    },
    "sort": ["balance"] 
}
GET /bank/_search
{
    "query": {
        "match_all": {}
    },
    "collapse" : {
        "field" : "age" ,                //指定inner_hits来解释折叠
        "inner_hits": {
            "name": "details",        //自命名
            "size": 5,     //指定每组取几个文档
            "sort": [{ "balance": "asc" }] //组内排序
        },
        "max_concurrent_group_searches": 4 //指定组查询的并发数
    },
    "sort": ["balance"] 
}

在inner_hits 中返回多个角度的组内topN

GET /twitter/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "user", 
        "inner_hits": [
            {
                "name": "most_liked",  
                "size": 3,
                "sort": ["likes"]
            },
            {
                "name": "most_recent", 
                "size": 3,
                "sort": [{ "date": "asc" }]
            }
        ]
    },
    "sort": ["likes"]
}

分页

  • from and size  
GET /_search
{
    "from" : 0, "size" : 10,
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}
//注意:搜索请求耗用的堆内存和时间与 from + size 大小成正比。分页越深耗用越大,为了不因分页导致OOM或严重影响性能,ES中规定from + size 不能大于索引setting参数 index.max_result_window 的值,默认值为 10,000。

需要深度分页, 不受index.max_result_window 限制,怎么办?

  • Search after  在指定文档后取文档, 可用于深度分页
GET twitter/_search
{                 //首次查询第一页
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "sort": [
        {"date": "asc"},
        {"_id": "desc"}
    ]
}
GET twitter/_search
{                   //后续页的查询
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "search_after": [1463538857, "654323"],
    "sort": [
        {"date": "asc"},
        {"_id": "desc"}
    ]
}

注意:使用search_after,要求查询必须指定排序,并且这个排序组合值每个文档唯一(最好排序中包含_id字段)。 search_after的值用的就是这个排序值。 用search_after时 from 只能为0、-1。

高亮  

PUT /hl_test/_doc/1
{
  "title": "lucene solr and elasticsearch",
  "content": "lucene solr and elasticsearch for search"
}
GET /hl_test/_search
{
  "query": {
    "match": {
      "title": "lucene"
    }
  },
  "highlight": {
    "fields": {
      "title": {},
      "content": {}
    }
  }
}
GET /hl_test/_search
{
  "query": {
    "match": {
      "title": "lucene"
    }
  },
  "highlight": {  //多字段高亮
    "require_field_match": false,
    "fields": {
      "title": {},
      "content": {}
    }
  }
}

高亮结果在返回的每个文档中以hightlight节点给出

"highlight": {
  "title": [
	"lucene solr and elaticsearch"
  ]}
GET /hl_test/_search
{
  "query": {
    "match": {
      "title": "lucene"
    }
  },
  "highlight": {
    "require_field_match": false,
    "fields": {
      "title": {
        "pre_tags":[""],
        "post_tags": [""]
      },
      "content": {}
    }
  }
}

Profile  为了调试、优化  

对于执行缓慢的查询,我们很想知道它为什么慢,时间都耗在哪了,可以在查询上加入上 profile 来获得详细的执行步骤、耗时信息。 

GET /twitter/_search
{
  "profile": true,
  "query" : {
    "match" : { "message" : "some number" }
  }
}

信息的说明请参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-profile.html

count  api

PUT /twitter/_doc/1?refresh
{
    "user": "kimchy"
}

GET /twitter/_doc/_count?q=user:kimchy

GET /twitter/_doc/_count
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}



{
    "count" : 1,
    "_shards" : {
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
    }
}

validate api  

用来检查我们的查询是否正确,以及查看底层生成查询是怎样的。

GET twitter/_validate/query?q=user:foo
GET twitter/_doc/_validate/query
{
  "query": {
    "query_string": {                   //校验查询
      "query": "post_date:foo",
      "lenient": false
    }
  }
}
GET twitter/_doc/_validate/query?explain=true
{
  "query": {            //获得查询解释
    "query_string": {
      "query": "post_date:foo",
      "lenient": false
    }
  }
}
GET twitter/_doc/_validate/query?rewrite=true
{
  "query": {
    "more_like_this": {
      "like": {
        "_id": "2"
      },
      "boost_terms": 1
    }
  }
}
//用rewrite获得比explain 更详细的解释
GET twitter/_doc/_validate/query?rewrite=true&all_shards=true
{
  "query": {
    "match": {
      "user": {
        "query": "kimchy",
        "fuzziness": "auto"
      }
    }
  }
}
//获得所有分片上的查询解释

Explain api  

获得某个查询的评分解释,及某个文档是否被这个查询命中

GET /twitter/_doc/0/_explain
{
      "query" : {
        "match" : { "message" : "elasticsearch" }
      }
}

Search Shards API

让我们可以了解可执行查询的索引分片节点情况

GET /twitter/_search_shards

想知道指定routing值的查询将在哪些分片节点上执行

GET /twitter/_search_shards?routing=foo,baz

Search Template

POST _scripts/
{
    "script": {
        "lang": "mustache",
        "source": {
            "query": {
                "match": {
                    "title": "{{query_string}}"
                }
            }
        }
    }
}
//注册一个模板
GET _search/template
{
    "id": "", 
    "params": {
        "query_string": "search for these words"
    }
}
//注册一个模板

Query DSL

Elasticsearch学习笔记之(四)搜索详解_第2张图片

DSL是什么?

Query and filter context

Domain Specific Language:领域特定语言 Elasticsearch基于JSON提供完整的查询DSL来定义查询。

一个查询可由两部分字句构成:

  • Leaf query clauses 叶子查询字句

            Leaf query clauses 在指定的字段上查询指定的值, 如:match, term or range queries. 叶子字句可以单独使用.

  • Compound query clauses  复合查询字句

            以逻辑方式组合多个叶子、复合查询为一个查询

Query and filter context

一个查询字句的行为取决于它是用在query context  还是 filter context 中 。

  •  Query context  查询上下文

          用在查询上下文中的字句回答“这个文档有多匹配这个查询?”。除了决定文档是否匹配,字节匹配的文档还会计算一个字节评分,来评定文档有多匹配。查询上下文由  query 元素表示。

  •  Filter context  过滤上下文

          过滤上下文由 filter 元素或 bool 中的 must not 表示。用在过滤上下文中的字节回答“这个文档是否匹配这个查询?”,不参与相关性评分。      被频繁使用的过滤器将被ES自动缓存,来提高查询性能。

Query and filter context

GET /_search
{
  "query": { 
    "bool": { 
      "must": [
        { "match": { "title":   "Search"        }}, 
        { "match": { "content": "Elasticsearch" }}  
      ],
      "filter": [ 
        { "term":  { "status": "published" }}, 
        { "range": { "publish_date": { "gte": "2015-01-01" }}} 
      ]
    }
  }
}
//提示:在查询上下文中使用查询子句来表示影响匹配文档得分的条件,并在过滤上下文中使用所有其他查询子句。

Elasticsearch学习笔记之(四)搜索详解_第3张图片

Match all query

查询所有

GET /_search
{
    "query": {
        "match_all": {}
    }
}
GET /_search
{
    "query": {
        "match_none": {}
    }
}

Full text querys

全文查询,用于对分词的字段进行搜索。会用查询字段的分词器对查询的文本进行分词生成查询。可用于短语查询、模糊查询、前缀查询、临近查询等查询场景

Elasticsearch学习笔记之(四)搜索详解_第4张图片

match query

全文查询的标准查询,它可以对一个字段进行模糊、短语查询。 match queries 接收 text/numerics/dates, 对它们进行分词分析, 再组织成一个boolean查询。可通过operator 指定bool组合操作(or、and 默认是 or ), 以及minimum_should_match 指定至少需多少个should(or)字句需满足。还可用ananlyzer指定查询用的特殊分析器。

GET /_search
{
    "query": {
        "match" : {
            "message" : "this is a test"
        }
    }
}

match query  示例

PUT /ftq/_doc/1
{
  "title": "lucene solr and elasticsearch",
  "content": "lucene solr and elasticsearch for search"
}

PUT /ftq/_doc/2
{
  "title": "java spring boot",
  "content": "lucene is writerd by java"
}
GET ftq/_doc/_validate/query?rewrite=true
{
  "query": {
    "match": {
      "title": "lucene java"
    }
  }
}
GET ftq/_search
{
  "query": {
    "match": {
      "title": "lucene java"
    }
  }
}
GET ftq/_search
{
  "query": {
    "match": {
      "title": {
        "query": "lucene java",
        "operator": "and"
      }
    }
  }
}
GET ftq/_search
{
  "query": {
    "match": {
      "title": {
        "query": "ucen elatic",
        "fuzziness": 2
      }
    }
  }
}
//模糊查询,最大编辑数为2
GET ftq/_search
{
  "query": {
    "match": {
      "content": {
        "query": "ucen elatic java",
        "fuzziness": 2,
        "minimum_should_match": 2
      }
    }
  }
}
//指定最少需满足两个词匹配

可用max_expansions 指定模糊匹配的最大词项数,默认是50。比如:反向索引中有 100 个词项与 ucen 模糊匹配,只选用前50 个。

match  phrase  query

match_phrase 查询用来对一个字段进行短语查询,可以指定 analyzer、slop移动因子。

GET ftq/_search
{
  "query": {
    "match_phrase": {
      "title": "lucene solr"
    }
  }
}
GET ftq/_search
{
  "query": {
    "match_phrase": {
      "title": "lucene elasticsearch"
    }
  }
}
GET ftq/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "lucene elasticsearch",
        "slop": 2
      }
    }
  }
}

match  phrase  prefix query

match_phrase_prefix  在 match_phrase 的基础上支持对短语的最后一个词进行前缀匹配

GET /_search
{
    "query": {
        "match_phrase_prefix" : {
            "message" : "quick brown f"
        }
    }
}
GET /_search
{
    "query": {
        "match_phrase_prefix" : {
            "message" : {
                "query" : "quick brown f",
                "max_expansions" : 10
            }
        }
    }
}
//指定前缀匹配选用的最大词项数量

Multi match  query

如果你需要在多个字段上进行文本搜索,可用multi_match 。 multi_match在 match的基础上支持对多个字段进行文本查询。

GET ftq/_search
{
  "query": {
    "multi_match" : {
      "query":    "lucene java", 
      "fields": [ "title", "content" ] 
    }
  }
}
GET ftq/_search
{
  "query": {
    "multi_match" : {
      "query":    "lucene java", 
      "fields": [ "title", "cont*" ] 
    }
  }
}
GET ftq/_search?explain=true
{
  "query": {
    "multi_match" : {
      "query":    "lucene elastic", 
      "fields": [ "title^5", "content" ] 
    }
  }
}
//给字段的相关性评分加权重

Common terms query

common 常用词查询

问1、什么是停用词?索引时做停用词处理的目的是什么?

问2、如果在索引时应用停用词处理,下面的两个查询会查询什么词项?     the brown fox     not happy

问3、索引时应用停用词处理对搜索精度是否有影响?如果不做停用词处理又会有什么影响?如何协调这两个问题?如何保证搜索的精确度又兼顾搜索性能?

tf-idf 相关性计算模型简介

tf:term frequency   词频 :指一个词在一篇文档中出现的频率。

如“世界杯”在文档A中出现3次,那么可以定义“世界杯”在文档A中的词频为3。请问在一篇3000字的文章中出现“世界杯”3次和一篇150字的文章中出现3词,哪篇文章更是与“世界杯”有关的。也就是说,简单用出现次数作为频率不够准确。那就用占比来表示:

Elasticsearch学习笔记之(四)搜索详解_第5张图片

问:tf值越大是否就一定说明这个词更相关?

说明:tf的计算不一定非是这样的,可以定义不同的计算方式。

df:document frequency   词的文档频率 :指包含某个词的文档数(有多少文档中包含这个词)。 df越大的词越常见,哪些词会是高频词?

问1:词的df值越大说明这个词在这个文档集中是越重要还是越不重要?

问2:词t的tf高,在文档集中的重要性也高,是否说明文档与该词越相关?举例:整个文档集中只有3篇文档中有“世界杯”,文档A中就出现了“世界级”好几次。

问3:如何用数值体现词t在文档集中的重要性?df可以吗?

用 文档总数 / df 可以吗?

idf:inverse document frequency   词的逆文档频率 :用来表示词在文档集中的重要性。文档总数/ df ,df越小,词越重要,这个值会很大,那就对它取个自然对数,将值映射到一个较小的取值范围。

Elasticsearch学习笔记之(四)搜索详解_第6张图片

说明: +1 是为了避免除0(即词t在文档集中未出现的情况)

tf-idf 相关性性计算模型:

Common terms query

common 区分常用(高频)词查询让我们可以通过cutoff_frequency来指定一个分界文档频率值,将搜索文本中的词分为高频词和低频词,低频词的重要性高于高频词,先对低频词进行搜索并计算所有匹配文档相关性得分;然后再搜索和高频词匹配的文档,这会搜到很多文档,但只对和低频词重叠的文档进行相关性得分计算(这可保证搜索精确度,同时大大提高搜索性能),和低频词累加作为文档得分。实际执行的搜索是 必须包含低频词 + 或包含高频词。

思考:这样处理下,如果用户输入的都是高频词如 “to be or not to be”结果会是怎样的?你希望是怎样的?

优化:如果都是高频词,那就对这些词进行and 查询。

进一步优化:让用户可以自己定对高频词做and/or 操作,自己定对低频词进行and/or  操作;或指定最少得多少个同时匹配。

GET /_search
{
    "query": {
        "common": {
            "message": {
                "query": "this is bonsai cool",
                "cutoff_frequency": 0.001
            }
        }
    }
}
//cutoff_frequency : 值大于1表示文档数,0-1.0表示占比。此处界定 文档频率大于 0.1%的词为高频词。
GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "nelly the elephant as a cartoon",
                "cutoff_frequency": 0.001,
                "low_freq_operator": "and"
            }
        }
    }
}

可用参数:minimum_should_match (high_freq, low_freq), low_freq_operator (default “or”) and high_freq_operator (default “or”)、 boost and analyzer

GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "nelly the elephant as a cartoon",
                "cutoff_frequency": 0.001,
                "minimum_should_match": 2
            }
        }
    }
}
GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "nelly the elephant not as a cartoon",
                "cutoff_frequency": 0.001,
                "minimum_should_match": {
                    "low_freq" : 2,
                    "high_freq" : 3
                }
            }
        }
    }
}
GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "how not to be",
                "cutoff_frequency": 0.001,
                "minimum_should_match": {
                    "low_freq" : 2,
                    "high_freq" : 3
                }
            }
        }
    }
}
//粗略等于右边的查询
GET /_search
{
    "query": {
        "bool": {
            "should": [
            { "term": { "body": "how"}},
            { "term": { "body": "not"}},
            { "term": { "body": "to"}},
            { "term": { "body": "be"}}
            ],
            "minimum_should_match": "3<50%"
        }
    }
}

Query string query

query_string 查询,让我们可以直接用lucene查询语法写一个查询串进行查询,ES中接到请求后,通过查询解析器解析查询串生成对应的查询。使用它要求掌握lucene的查询语法。

GET /_search
{
    "query": {
        "query_string" : {
            "default_field" : "content",
            "query" : "this AND that OR thus"
        }
    }
}
GET /_search
{
    "query": {
        "query_string" : {
            "fields" : ["content", "name.*^5"],
            "query" : "this AND that OR thus"
        }
    }
}

可与query同用的参数,如 default_field、fields,及query 串的语法请参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html

查询描述规则语法(查询解析语法):

Term 词项

           单个词项的表示:     电脑 短语的表示:     "联想笔记本电脑"

Field 字段:

           字段名:

               示例: name:“联想笔记本电脑” AND type:电脑 如果name是默认字段,则可写成: “联想笔记本电脑” AND type:电脑 如果查询串是:type:电脑 计算机 手机 注意:只有第一个是type的值,后两个则是使用默认字段。

Term Modifiers 词项修饰符:

Elasticsearch学习笔记之(四)搜索详解_第7张图片

Term Modifiers 词项修饰符:

范围查询:

     mod_date:[20020101 TO 20030101]       包含边界值

     title:{Aida TO Carmen}      不包含边界值

词项加权,使该词项的相关性更高,通过 ^数值来指定加权因子,默认加权因子值是1

示例:如要搜索包含 jakarta apache 的文章,jakarta更相关,则: jakarta^4 apache

短语也可以: "jakarta apache"^4 "Apache Lucene"

Boolean 操作符   Lucene支持的布尔操作: AND, “+”, OR, NOT ,"-"

OR

"jakarta apache" jakarta = "jakarta apache" OR jakarta

AND

"jakarta apache" AND "Apache Lucene"

+  必须包含

+jakarta lucene

NOT   非

"jakarta apache" NOT "Apache Lucene“ 注意:NOT不可单项使用: NOT “Apache Lucene“     不可

-    同NOT

"jakarta apache"  -"Apache Lucene“

组合 ()  

     字句组合

           (jakarta OR apache) AND website

     字段组合

            title:(+return +"pink panther")

转义   \

对语法字符: + - && || ! ( ) { } [ ] ^ “ ~ * ? : \ /     进行转义。 如要查询包含 (1+1):2        \(1\+1\)\:2

Simple Query string query

simple_query_string 查同 query_string 查询一样用lucene查询语法写查询串,较query_string不同的地方:更小的语法集;查询串有错误,它会忽略错误的部分,不抛出错误。更适合给用户使用。

GET /_search
{
  "query": {
    "simple_query_string" : {
        "query": "\"fried eggs\" +(eggplant | potato) -frittata",
        "fields": ["title^5", "body"],
        "default_operator": "and"
    }
  }
}

语法请参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html

Term level querys

Elasticsearch学习笔记之(四)搜索详解_第8张图片

https://www.elastic.co/guide/en/elasticsearch/reference/current/term-level-queries.html

Term query

term 查询用于查询指定字段包含某个词项的文档。

POST _search
{
  "query": {
    "term" : { "user" : "Kimchy" } 
  }
}
GET _search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "status": {
              "value": "urgent",
              "boost": 2.0 
            }
          }
        },
        {
          "term": {
            "status": "normal" 
          }
        }      ]    }  }}

terms 查询用于查询指定字段包含某些词项的文档。

GET /_search
{
    "query": {
        "terms" : { "user" : ["kimchy", "elasticsearch"]}
    }
}

Terms 查询支持嵌套查询的方式来获得查询词项,相当于 in (select term from other)

Terms query  嵌套查询示例

PUT /users/_doc/2
{
    "followers" : ["1", "3"]
}

PUT /tweets/_doc/1
{
    "user" : "1"
}

GET /tweets/_search
{
    "query" : {
        "terms" : {
            "user" : {
                "index" : "users",
                "type" : "_doc",
                "id" : "2",
                "path" : "followers"
            }
        }    }}

嵌套查询可用参数说明:

index 

The index to fetch the term values from. 

type 

The type to fetch the term values from. 

id 

The id of the document to fetch the term values from. 

path 

The field specified as path to fetch the actual values for the terms filter. 

routing 

A custom routing value to be used when retrieving the external terms doc. 

 

range query

GET _search
{
    "query": {
        "range" : {
            "age" : {
                "gte" : 10,
                "lte" : 20,
                "boost" : 2.0
            }
        }
    }
}
GET _search
{
    "query": {
        "range" : {
            "date" : {
                "gte" : "now-1d/d",
                "lt" :  "now/d"
            }
        }
    }
}
GET _search
{
    "query": {
        "range" : {
            "born" : {
                "gte": "01/01/2012",
                "lte": "2013",
                "format": "dd/MM/yyyy||yyyy"
            }
        }
    }
}

gte 

Greater-than or equal to 

gt 

Greater-than 

lte 

Less-than or equal to 

lt 

Less-than 

boost 

Sets the boost value of the query, defaults to 1.0 

 

range query

时间舍入 ||说明:

gt 

Greater than the date rounded up: 2014-11-18||/M becomes 2014-11-30T23:59:59.999, ie excluding the entire month. 

gte 

Greater than or equal to the date rounded down: 2014-11-18||/M becomes 2014-11-01, ie including the entire month. 

lt 

Less than the date rounded down: 2014-11-18||/M becomes 2014-11-01, ie excluding the entire month. 

lte 

Less than or equal to the date rounded up: 2014-11-18||/M becomes 2014-11-30T23:59:59.999, ie including the entire month. 

 

时间数学计算规则请参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math

exists  query

查询指定字段值不为空的文档。相当 SQL 中的  column is not null

GET /_search
{
    "query": {
        "exists" : { "field" : "user" }
    }
}
GET /_search
{
    "query": {
        "bool": {
            "must_not": {
                "exists": {
                    "field": "user"
                }
            }        }    }}
//查询指定字段值为空的文档

prefix  query   词项前缀查询

GET /_search
{ "query": {
    "prefix" : { "user" : "ki" }
  }
}
GET /_search
{ "query": {
    "prefix" : { "user" :  { "value" : "ki", "boost" : 2.0 } }
  }
}

wildcard  query   通配符查询:  ?  *

GET /_search
{ "query": {
    "prefix" : { "user" : "ki" }
  }
}
GET /_search
{ "query": {
    "prefix" : { "user" :  { "value" : "ki", "boost" : 2.0 } }
  }
}

regexp query   正则查询

GET /_search
{
    "query": {
        "regexp":{
            "name.first": "s.*y"
        }
    }
}
GET /_search
{
    "query": {
        "regexp":{
            "name.first":{
                "value":"s.*y",
                "boost":1.2
            }
        }
    }
}

正则语法请参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html#regexp-syntax

fuzzy query   模糊查询

GET /_search
{
    "query": {
       "fuzzy" : { "user" : "ki" }
    }
}
GET /_search
{
    "query": {
        "fuzzy" : {
            "user" : {
                "value": "ki",
                "boost": 1.0,
                "fuzziness": 2,
                "prefix_length": 0,
                "max_expansions": 100
            }
        }
    }
}

type query   mapping type 查询

GET /_search
{
    "query": {
        "type" : {
            "value" : "_doc"
        }
    }
}

ids query   根据文档id查询

GET /_search
{
    "query": {
        "ids" : {
            "type" : "_doc",
            "values" : ["1", "4", "100"]
        }
    }
}

Compound querys 复合查询

Elasticsearch学习笔记之(四)搜索详解_第9张图片

https://www.elastic.co/guide/en/elasticsearch/reference/current/compound-queries.html

Constant Score query

用来包装另一个查询,将查询匹配的文档的评分设为一个常值。

GET /_search
{
    "query": {
        "constant_score" : {
            "filter" : {
                "term" : { "user" : "kimchy"}
            },
            "boost" : 1.2
        }
    }
}

Bool query

Bool 查询用bool操作来组合多个查询字句为一个查询。 可用的关键字:

Occur 

Description

must

 必须满足

filter

必需满足,但执行的是filter上下文,不影响评分

should

must_not

必须不满足,在 filter 上下文中执行

 

POST _search
{
  "query": {
    "bool" : {
      "must" : {
        "term" : { "user" : "kimchy" }
      },
      "filter": {
        "term" : { "tag" : "tech" }
      },
      "must_not" : {
        "range" : {
          "age" : { "gte" : 10, "lte" : 20 }
        }
      },
      "should" : [
        { "term" : { "tag" : "wow" } },
        { "term" : { "tag" : "elasticsearch" } }
      ],
      "minimum_should_match" : 1,
      "boost" : 1.0
    }
  }
}

 

你可能感兴趣的:(elasticserach,搜索引擎)