相关文章推荐
鬼畜的椰子  ·  Docker ...·  4 月前    · 
欢快的伤痕  ·  ACCESS ...·  1 年前    · 
行走的烤红薯  ·  PyQt5笔记(02) -- ...·  1 年前    · 

默认情况下,返回的结果是按照 相关性 进行排序的——最相关的文档排在最前。

1.按照字段的值排序

在这个案例中,通过时间来对 tweets 进行排序是有意义的,最新的 tweets 排在最前。 我们可以使用 sort 参数进行实现:

GET /_search
    "query" : {
        "bool" : {
            "filter" : { "term" : { "user_id" : 1 }}
    "sort": { "date": { "order": "desc" }}

2.多级排序

假定我们想要结合使用 date 和 _score 进行查询,并且匹配的结果首先按照日期排序,然后按照相关性排序:

GET /_search
    "query" : {
        "bool" : {
            "must":   { "match": { "tweet": "manage text search" }},
            "filter" : { "term" : { "user_id" : 2 }}
    "sort": [
        { "date":   { "order": "desc" }},
        { "_score": { "order": "desc" }}

3.多值字段的排序

一种情形是字段有多个值的排序, 需要记住这些值并没有固有的顺序;一个多值的字段仅仅是多个值的包装,这时应该选择哪个进行排序呢?

对于数字或日期,你可以将多值字段减为单值,这可以通过使用 min 、 max 、 avg 或是 sum 排序模式 。 例如你可以按照每个 date 字段中的最早日期进行排序,通过以下方法:

"sort": {
    "dates": {
        "order": "asc",
        "mode":  "min"

4.字符串排序与多字段

被解析的字符串字段也是多值字段, 但是很少会按照你想要的方式进行排序。如果你想分析一个字符串,如 fine old art , 这包含 3 项。我们很可能想要按第一项的字母排序,然后按第二项的字母排序,诸如此类,但是 Elasticsearch 在排序过程中没有这样的信息。

你可以使用 min 和 max 排序模式(默认是 min ),但是这会导致排序以 art 或是 old ,任何一个都不是所希望的。

我们真正想要做的是传递一个 单字段 但是却用两种方式索引它。所有的 _core_field 类型 (strings, numbers, Booleans, dates) 接收一个 fields 参数

该参数允许你转化一个简单的映射如:

"tweet": {
    "type":     "string",
    "analyzer": "english"

为一个多字段映射如:

"tweet": { 
    "type":     "string",
    "analyzer": "english",
    "fields": {
        "raw": { 
            "type":  "string",
            "index": "not_analyzed"

tweet 主字段与之前的一样: 是一个 analyzed 全文字段。
新的 tweet.raw 子字段是 not_analyzed.

现在,至少只要我们重新索引了我们的数据,使用 tweet 字段用于搜索,tweet.raw 字段用于排序:

GET /_search
    "query": {
        "match": {
            "tweet": "elasticsearch"
    "sort": "tweet.raw"

以全文 analyzed 字段排序会消耗大量的内存。

5.什么是相关性?

我们曾经讲过,默认情况下,返回结果是按相关性倒序排列的。 但是什么是相关性? 相关性如何计算?

每个文档都有相关性评分,用一个正浮点数字段 _score 来表示 。 _score 的评分越高,相关性越高。

Elasticsearch 的相似度算法被定义为检索词频率/反向文档频率, TF/IDF ,包括以下内容:

检索词频率

检索词在该字段出现的频率?出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高。

反向文档频率

每个检索词在索引中出现的频率?频率越高,相关性越低。检索词出现在多数文档中会比出现在少数文档中的权重更低。

字段长度准则

字段的长度是多少?长度越长,相关性越低。 检索词出现在一个短的 title 要比同样的词出现在一个长的 content 字段权重更大。

单个查询可以联合使用 TF/IDF 和其他方式,比如短语查询中检索词的距离或模糊查询里的检索词相似度。

5.1理解评分标准

当调试一条复杂的查询语句时,想要理解 _score 究竟是如何计算是比较困难的。Elasticsearch 在 每个查询语句中都有一个 explain 参数,将 explain 设为 true 就可以得到更详细的信息。

GET /_search?explain 
   "query"   : { "match" : { "tweet" : "honeymoon" }}
"_explanation": { //honeymoon 相关性评分计算的总结
   "description": "weight(tweet:honeymoon in 0)
                  [PerFieldSimilarity], result of:",
   "value":       0.076713204,
   "details": [
      { //honeymoon 相关性评分计算的总结
         "description": "fieldWeight in 0, product of:",
         "value":       0.076713204,
         "details": [
            {  //检索词频率
               "description": "tf(freq=1.0), with freq of:",
               "value":       1,
               "details": [
                     "description": "termFreq=1.0",
                     "value":       1
            { //反向文档频率
               "description": "idf(docFreq=1, maxDocs=1)",
               "value":       0.30685282
            { //字段长度准则
               "description": "fieldNorm(doc=0)",
               "value":        0.25,

输出 explain 结果代价是十分昂贵的,它只能用作调试工具 。千万不要用于生产环境。

第一部分是关于计算的总结。告诉了我们 honeymoon 在 tweet 字段中的检索词频率/反向文档频率或TF/IDF, (这里的文档 0 是一个内部的 ID,跟我们没有关系,可以忽略。)

然后它提供了权重是如何计算的细节:

检索词频率:

检索词 `honeymoon` 在这个文档的 `tweet` 字段中的出现次数。

反向文档频率:

检索词 `honeymoon` 在索引上所有文档的 `tweet` 字段中出现的次数。

字段长度准则:

在这个文档中, `tweet` 字段内容的长度 -- 内容越长,值越小。

复杂的查询语句解释也非常复杂,但是包含的内容与上面例子大致相同。 通过这段信息我们可以了解搜索结果是如何产生的。

6.Doc Values 介绍

本章的最后一个话题是关于 Elasticsearch 内部的一些运行情况。在这里我们先不介绍新的知识点,所以我们应该意识到,Doc Values 是我们需要反复提到的一个重要话题。

当你对一个字段进行排序时,Elasticsearch 需要访问每个匹配到的文档得到相关的值。倒排索引的检索性能是非常快的,但是在字段值排序时却不是理想的结构。

  • 在搜索的时候,我们能通过搜索关键词快速得到结果集。
  • 当排序的时候,我们需要倒排索引里面某个字段值的集合。换句话说,我们需要 转置 倒排索引。

转置 结构在其他系统中经常被称作 列存储 。实质上,它将所有单字段的值存储在单数据列中,这使得对其进行操作是十分高效的,例如排序。

在 Elasticsearch 中,Doc Values 就是一种列式存储结构,默认情况下每个字段的 Doc Values 都是激活的,Doc Values 是在索引时创建的,当字段索引时,Elasticsearch 为了能够快速检索,会把字段的值加入倒排索引中,同时它也会存储该字段的 Doc Values

Elasticsearch 中的 Doc Values 常被应用到以下场景:

  • 对一个字段进行排序
  • 对一个字段进行聚合
  • 某些过滤,比如地理位置过滤
  • 某些与字段相关的脚本计算

因为文档值被序列化到磁盘,我们可以依靠操作系统的帮助来快速访问。当 working set 远小于节点的可用内存,系统会自动将所有的文档值保存在内存中,使得其读写十分高速; 当其远大于可用内存,操作系统会自动把 Doc Values 加载到系统的页缓存中,从而避免了 jvm 堆内存溢出异常。

我们稍后会深入讨论 Doc Values。现在所有你需要知道的是排序发生在索引时建立的平行数据结构中。

备注:文章参考Elasticsearch: 权威指南

https://www.elastic.co/guide/cn/elasticsearch/guide/current/sorting.html

默认情况下,返回的结果是按照相关性进行排序的——最相关的文档排在最前。1.按照字段的值排序在这个案例中,通过时间来对 tweets 进行排序是有意义的,最新的 tweets 排在最前。 我们可以使用sort参数进行实现:GET /_search{ "query" : { "bool" : { "filter" : { "term" : { "user_id" : 1 }} } }, "sort": { "...
Elasticsearch搜索引擎Suggest查询建议-权重 重要:在加载数据库数据到es时,对索引字段“suggest_name”设置的值 进行修改 原:对索引字段直接进行设值,如:"suggest_name": "空调" 改:对索引字段进行编制,加入es的提供的权重判断,改为设值为: "suggest_name": { "input": "空调", "weight": 50 备注: 50 为 ,1个字在整个字符串中的占比,比如“空”就占 50%,“调”字类
现在要根据关键字去检索数据,我们主要是根据name和address去检索数据,给name和address分配配置上相应的score,然后根据评分排序 另外也会传一个城市名称,需要对上面检索出的数据,再加上城市名称的评分,最后再排序 比如说有3条数据如下
在很多复杂的业务场景下,排序的规则会比较复杂,单一的降序,升序无法满足日常需求。不过 ES 中提供了给文档加权重的方式来排序,还是挺好用的。 首先初始化三条测试数据,方便查看效果: id: 1, title: "Java怎么学", type: 3, userId: 1, tags: [ "java" textContent: "我要学Java", status: 1, heat: 80 id: 2, title: "Java怎么学", type: 2, es搜索keyWord字段,需要给es指定字段weight加上系数进行排序 二、建立测试索引 curl -XDELETE 'http://flxapp01:9200/local_service' curl -X PUT '192.168.1.96:9200/local_service?pretty' \ -H 'Accept: application/json,text/plain, */*' \ -H 'Content-Type: application/json;charset=UTF-8'
最近去兄弟部门的新自定义查询项目组搬砖,项目使用Elasticsearch进行数据的检索和查询。每一个查询页面都需要根据选择的字段进行排序,以为是一个比较简单的需求,其实实现起来还是比较复杂的。这里进行一个总结,加深一下记忆。 Elasticsearch是什么? Elasticsearch 简称ES,是一个全文搜索引擎,可以实现类似百度搜索的功能。但她不仅仅能进行全文检索,还可以实现PB级数据的近实时分析和精确查找,还可以作GIS数据库,进行AI机器学习,功能非常强大。
ES倒排索引及类型映射与分析器/SE倒排及搜索实现基础前言1 数据类型映射2 非结构化的全文文本查询与倒排索引(模糊的相关度的查询方式与倒排索引)3 分析器3.1 字符过滤器3.2 分词器3.3 标记过滤4. 映射注意5 复合类型5.1 多值字段5.2 空值5.3 多层对象 ES快速搜索的基础是建立在逆序索引设计的基础上的, 逆序索引的建立最基础的设计则是对于字符串的词语拆分 ; 通过将全文...
映射是用于定义 ES 对索引中字段的存储类型、分词方式和是否存储等信息,就像数据库中的 Schema ,描述了文档可能具有的字段或属性、每个字段的数据类型。 只不过关系型数据库建表时必须指定字段类型,而 ES 对于字段类型可以不指定然后动态对字段类型猜测,也可以在创建索引时具体指定字段的类型。 对字段类型根据数据格式自动识别的映射称之为动态映射(Dynamic Mapping),我们创建索引时具体...
在这个查询中,我们使用`match_all`查询来匹配所有的文档。通过在`sort`中指定子文档字段的排序顺序,我们可以对子文档进行排序。同时,通过在`inner_hits`中指定子文档的排序顺序,我们可以对内部命中的子文档进行排序。 请根据你的具体需求和索引映射来调整这个查询。确保在使用之前详细阅读Elasticsearch官方文档以了解更多关于`has_child`查询和`inner_hits`的信息。