聚合

  1. 聚合有以下四个种类
  1. Bucket Aggregation  一些列满足特定条件的文档的集合,给字段分桶,比如给性别分类,一个user文档属于哪个性别。
GET movies/_search
{
  "size": 0,
  "aggs": {
    "year": {
      "terms": {
        "field": "year"
      }
    }
  }
}

简单分桶,对年份进行分桶,aggs下的year为自定义名称,用来辨别响应集合,一下是响应

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10000,
      "relation" : "gte"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "year" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 14954,
      "buckets" : [
        {
          "key" : 0,
          "doc_count" : 5169
        },
        {
          "key" : 2013,
          "doc_count" : 902
        },
        {
          "key" : 2009,
          "doc_count" : 885
        },
        {
          "key" : 2012,
          "doc_count" : 872
        },
        {
          "key" : 2011,
          "doc_count" : 850
        },
        {
          "key" : 2008,
          "doc_count" : 785
        },
        {
          "key" : 2010,
          "doc_count" : 766
        },
        {
          "key" : 2007,
          "doc_count" : 724
        },
        {
          "key" : 2014,
          "doc_count" : 701
        },
        {
          "key" : 2006,
          "doc_count" : 672
        }
      ]
    }
  }
}
  1. Metric Aggregation  一些数学运算,可以对文档进行统计分析,可以在字段上也可以在脚本产生的结果之上进行计算。
GET movies/_search
{
  "size": 0,
  "aggs": {
    "year": {
      "terms": {
        "field": "year"
      },
      "aggs": {
        "sum_year": {
          "sum": {
            "field": "year"
          }
        }
      }
    }
  }
}

首先对year进行分桶,然后对桶内的集合施加二次聚合,把桶内的年份加起来,其中,二次聚合的关键词aggs与分桶字段year同级,es会依次执行,以下是响应

{
  "took" : 27,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10000,
      "relation" : "gte"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "year" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 14954,
      "buckets" : [
        {
          "key" : 0,
          "doc_count" : 5169,
          "sum_year" : {
            "value" : 0.0
          }
        },
        {
          "key" : 2013,
          "doc_count" : 902,
          "sum_year" : {
            "value" : 1815726.0
          }
        },
        {
          "key" : 2009,
          "doc_count" : 885,
          "sum_year" : {
            "value" : 1777965.0
          }
        },
        {
          "key" : 2012,
          "doc_count" : 872,
          "sum_year" : {
            "value" : 1754464.0
          }
        },
        {
          "key" : 2011,
          "doc_count" : 850,
          "sum_year" : {
            "value" : 1709350.0
          }
        },
        {
          "key" : 2008,
          "doc_count" : 785,
          "sum_year" : {
            "value" : 1576280.0
          }
        },
        {
          "key" : 2010,
          "doc_count" : 766,
          "sum_year" : {
            "value" : 1539660.0
          }
        },
        {
          "key" : 2007,
          "doc_count" : 724,
          "sum_year" : {
            "value" : 1453068.0
          }
        },
        {
          "key" : 2014,
          "doc_count" : 701,
          "sum_year" : {
            "value" : 1411814.0
          }
        },
        {
          "key" : 2006,
          "doc_count" : 672,
          "sum_year" : {
            "value" : 1348032.0
          }
        }
      ]
    }
  }
}

其中key是年份,doc_count即此年份在文档中出现的次数,而sum_year下即为当前年分桶下的年份和。

  1. Pipeline Aggregation  对其他的聚合结果进行二次聚合
  2. Matrix Aggregation 支持对多个字段的操作并提供一个结果矩阵
  1. term查询与全文查询的区别
  1. term查询对输入不做分词,会将输入作为一个整体,在倒排索引中查找精准的词项,并使用相关算分工时为每个包含该词项的文档进行相关性打分
  2. match查询,回会输入做分词处理,并进行相关性打分。
  1. 多值字段查询
GET movies/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "genre.keyword": "Adventure"
        }
      }
    }
  }
}

使用字段.keywor的形式进行多值字段查询,以下是查询结果

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2329,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "movies",
        "_type" : "_doc",
        "_id" : "126",
        "_score" : 1.0,
        "_source" : {
          "year" : 1994,
          "genre" : [
            "Adventure",
            "Children",
            "Fantasy"
          ],
          "@version" : "1",
          "id" : "126",
          "title" : "NeverEnding Story III, The"
        }
      },
      {
        "_index" : "movies",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "year" : 1995,
          "genre" : [
            "Adventure",
            "Children",
            "Fantasy"
          ],
          "@version" : "1",
          "id" : "2",
          "title" : "Jumanji"
        }
      }
    ]
  }
}

会筛选出genre中含有adventure的文档,如果使用genre进行查询会查不到数据,因为genre中的数据与genre是包含的关系,而不是相等的关系。

  1. 相关性和相关性算分
  1. es5之前采用的是TF-IDF算法,而es5之后采用的是BM25算法
  2. 相关性酸粉,描述了一个文档和查询语句匹配的程度,es会对每个匹配查询条件的结果进行算分_score
  3. 词频TF:检索词出现的次数除以文档的总字数,简单的将搜索中的每一个词的TF相加,TF(分词1) + TF(分词2)

2019-10-23

昨天产品插入了个需求,还要昨天就上线,加上凌晨有活动开启,要观测情况,一直搞倒了凌晨两点,结果我8点又来公司上班了,哈哈哈哈哈

下面插入一个更,因为周五有波分享,所以我想先学习下简单的重建索引reindex

都知道elasticsearch索引一旦建立,就无法动态修改其字段的映射类型,有时候因为人为原因污染了索引的mapping,这个时候就只能通过重建索引来修改索引的mapping设置了。

如果想更改索引,一般有以下两种情况

1.给这个索引追加一个新的字段,同时给这个字段指定类型

   但是这种方式会造成数据冗余、数据不同步的情况发生。尽量不要用

2.使用es的reindex api 创建新的索引,然后使用reindex将原来的索引重建到新索引即可,不过这样是停机迁移

PUT user/_doc/1
{
  "name":"PHPer"
}

首先创建被迁移索引,es会创建默认的mapping

{
  "user" : {
    "mappings" : {
      "properties" : {
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

mapping如上,如果现在要做索引重建

PUT new_user

PUT new_user/_mapping
{
  "properties":{
    "name":{
      "type":"keyword"
    }
  }
}

需要创建新索引,然后设置新的mapping

POST _reindex
{
  "source": {
    "index": "user",
    "size": 1
  },
  "dest": {
    "index": "new_user"
  }
}

使用reindex进行数据迁移,source中指定size使用scroll模式进行数据迁移,默认size1000

{
  "took" : 14,
  "timed_out" : false,
  "total" : 2,
  "updated" : 2,
  "created" : 0,
  "deleted" : 0,
  "batches" : 2,
  "version_conflicts" : 0,
  "noops" : 0,
  "retries" : {
    "bulk" : 0,
    "search" : 0
  },
  "throttled_millis" : 0,
  "requests_per_second" : -1.0,
  "throttled_until_millis" : 0,
  "failures" : [ ]
}

迁移结果如上,如果执行一次迁移,应该是created中是2,由于我第二次操作,属于在新索引上执行修改操作,所以,updated是2

2019-10-26

  • 别名 
POST _aliases
{
  "actions": [
    {
      "remove": {"index": "movies","alias": "myindex"}
    },
    {
      "add": {"index": "movies_new","alias": "myindex"}
    }
  ]
}

使用alias api进行别名处理,一个索引可以有多个别名,一个别名也可以只想多个索引,actions间的行为时原子性的。如果一个别名指向多个索引,那么当查看索引别名时会查所有指向别名的索引。

  • 查看当前别名指向哪些索引
GET _alias/myindex1

结果

{
  "movies_new" : {
    "aliases" : {
      "myindex1" : { }
    }
  },
  "movies" : {
    "aliases" : {
      "myindex1" : { }
    }
  }
}
  • 查看当前索引有哪些别名
GET movies_new/_alias

结果

{
  "movies_new" : {
    "aliases" : {
      "myindex1" : { }
    }
  },
  "movies" : {
    "aliases" : {
      "myindex1" : { }
    }
  }
}