目录:
集群(cluster): 由一个或多个节点组成, 并通过集群名称与其他集群进行区分
节点(node): 单个ElasticSearch实例. 通常一个节点运行在一个隔离的容器或虚拟机中
索引(index): 在ES中, 索引是一组文档的集合
分片(shard): 因为ES是个分布式的搜索引擎, 所以索引通常都会分解成不同部分, 而这些分布在不同节点的数据就是分片. ES自动管理和组织分片, 并在必要的时候对分片数据进行再平衡分配, 所以用户基本上不用担心分片的处理细节,一个分片默认最大文档数量是20亿.
副本(replica): ES默认为一个索引创建5个主分片, 并分别为其创建一个副本分片. 也就是说每个索引都由5个主分片成本, 而每个主分片都相应的有一个copy.
映射(mapping): 映射是定义文档及其包含的字段如何存储和索引的过程。例如,使用映射来定义:应该将哪些字符串字段视为全文字段。哪些字段包含数字、日期或地理位置。日期值的格式。用于控制动态添加字段的映射的自定义规则。
实际数据建立映射
数据预览:
movie_id | title | rating | releasedate | introduction | genre | actors |
---|---|---|---|---|---|---|
13 | Forrest Gump | 8.3 | 1994/7/6 | 阿甘(汤姆·汉克斯 Tom Hanks 饰)于二战结束后不久出生在美国南方阿拉巴马州一个闭塞的小镇,他先天弱智,智商只有75,然而他的妈妈是一个性格坚强的女性,她常常鼓励阿甘“傻人有傻福”,要他自强不息。阿甘像普通孩子一样上学,并且认识了一生的朋友和至爱珍妮(罗宾·莱特·潘 Robin Wright Penn 饰),在珍妮和妈妈的爱护下,阿甘凭着上帝赐予的“飞毛腿”开始了一生不停的奔跑。阿甘成为橄榄球巨星、越战英雄、乒乓球外交使者、亿万富翁,但是,他始终忘不了珍妮,几次匆匆的相聚和离别,更是加深了阿甘的思念。有一天,阿甘收到珍妮的信,他们终于又要见面… | 爱情 | Michael McFall |
24 | Kill Bill: Vol. 1 | 7.8 | 2003/10/10 | 新娘(乌玛·瑟曼饰)曾经是致命毒蛇暗杀小组(D.I.V.A.S)的一员,企图通过结婚脱离血腥的生活。但是她的前同僚(汉纳、刘玉玲、薇薇卡·A·福克斯、迈克尔·马德森等人扮演)以及所有人的老板比尔(大卫·卡拉丁饰)的到来破坏了这一切。“比尔,”新娘请求说,“我怀孕了,是你的孩子。”但是回答她的是“砰”的一声枪响!4年后她在一家医院醒来,就立刻开始着手一次从得克萨斯到冲绳、东京以及墨西哥的复仇之旅,为了一个目标她要大开杀戒。“当我到达目的地之后,我将杀死比尔。” | 犯罪 | 刘家辉 |
79 | 英雄 | 7.3 | 2002/12/19 | 战国末期,赵国有三个名震天下的侠客,他们是:“长空”、“残剑”、“飞雪”。因为他们,秦王十年里没睡过一个安稳觉。可是他们却被一个默默无闻,名叫无名的秦国剑客所杀。消息传来,秦王振奋,急召无名上殿相见。在秦王的大殿里,神秘的烛火燃烧着,秦王与无名只有十步的距离,无名将击杀长空、残剑、飞雪的故事娓娓道来:他利用三人之间爱恨交织的关系,瓦解了他们的力量,各个击破,因此取胜。可秦王机智过人,听出了无名故事中的破绽,说出了另一个故事的**:残剑等三人是主动求败,献出生命,用苦肉计帮助无名上殿,无名才是真正最危险的刺客,而无名告诉秦王:他看错了一个人,那就是残剑。于是真正的故事从头叙起……最后,无名拿起了剑,此时他离秦王只有十步,他的绝技是“十步一杀”。 | 历史 | "李连杰 |
82 | Miami Vice | 5.6 | 2006/7/27 | 故事背景从上世纪80年代变成了现代的迈阿密,美国南部城市迈阿密一直以来都是毒品犯罪的“茂盛”繁殖 地。美国联邦调查局(FBI)更是从来都没有放松过对这一带地区的监控,尤其是那些享誉拉美的大毒枭们,早已成为了警方最为关注的焦点。当前,正有一个棘手的大宗毒品走私案在紧张的调查中。迈阿密警方自然也派出了多位精明强干的警探参与其中,黑人警察里卡多(杰米·福克斯)与詹姆斯·科罗凯特(柯林·法瑞尔)一个正面追查毒品走私的线路,一个则假扮成小毒贩,卧底于一个较大的贩毒团伙内。然而,在时间不长的卧底调查中,个性夸张的詹姆斯不知不觉中陷入了与性感女银行家伊莎贝拉(巩俐)的私密恋情之中。然而,这个亚裔女人实际上就是本地毒品走私集团幕后的重要头目,并且是远近闻名的大毒枭兼军火商蒙托亚(路易斯·多萨)的女人。两人离奇的恋情给整个案件的侦破带来了空前的麻烦和危险。“黑白干探”、性感女毒犯以及凶残的大毒枭……所有的一切“黑白之物”都在一瞬间纠缠在了一起。 | 犯罪 | 巩俐 |
87 | Indiana Jones and the Temple of Doom | 7.0 | 1984/5/23 | 中国,印第安纳琼斯博士(Harrison Ford饰)与上海黑帮老大交易,对方在换得努尔哈赤的骨灰后便背信弃义,欲灭琼斯之口。关键时刻,机灵小鬼豆丁(Jonathan Ke Quan饰)救下琼斯博士和无故卷进的一位歌女威莉(Kate Capshaw饰)。由于三人乘坐的飞机失事,跳机后,乘着橡皮艇,他们竟漂流到了印度的一个村子。这里河水干涸,庄稼尽毁,饥荒横行,民不聊生。当地人将之归咎为彭高皇宫的妖孽作怪,并将“从天而降”的琼斯一行视为神灵的化身,他们请求琼斯帮他们拿回被掳走的圣石和所有的小孩子。魔宫果然充满古怪,统治者是个小屁孩,贵族们吃水蛭、巨蟒、甲虫、猴脑,皇宫内部更是机关重重,误打误撞间,他们目睹到血腥的邪教献祭仪式……这一仗注定艰苦异常! | 动作 | 乔宏 |
PUT movie
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 3,
"max_result_window": 100000000
},
"mappings": {
"mm": {
"properties": {
"actors": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
},
"fielddata": true ①
},
"genre": {
"type": "keyword"
},
"introduction": {
"type": "text"
},
"movie_id": {
"type": "long"
},
"rating": {
"type": "float"
},
"releasedate": {
"type": "date",
"format":"yyyy/MM/dd"
},
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
①fielddata 它是通过从磁盘读取每个段的整个反向索引来构建的
PUT testinfo_index
{
"mappings": {
"testinfo_type": {
"properties": {
"id": {
"type": "long"
},
"title": {
"type": "keyword"
},
"content": {
"analyzer": "standard",
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
},
"available": {
"type": "boolean"
},
"review": {
"type": "nested",
"properties": {
"nickname": {
"type": "text"
},
"text": {
"type": "text"
},
"stars": {
"type": "integer"
}
}
},
"publish_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"expected_attendees": {
"type": "integer_range"
},
"ip_addr": {
"type": "ip"
},
"suggest": {
"type": "completion"
}
}
}
}
}
分词器:从一串文本中切分出一个一个的词条,并对每个词条进行标准化
倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。
在搜索引擎中,查询词可以切分成若干个单词,所以对于搜索引擎中的倒排索引对应的属性就是单词,而对应的记录就是网页(也可以广泛地称为是文档)。所以,搜索引擎中的倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词(属性)快速获取包含这个单词的文档列表(记录)。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。
假设文档集合包含五个文档,每个文档内容下图所示,在图中最左端一栏是每个文档对应的文档编号。我们的任务就是对这个文档集合建立倒排索引。
中文和英文等语言不同,单词之间没有明确分隔符号,所以首先要用分词系统将文档自动切分成单词序列。这样每个文档就转换为由单词序列构成的数据流,为了系统后续处理方便,需要对每个不同的单词赋予唯一的单词编号,同时记录下哪些文档包含这个单词,在如此处理结束后,我们可以得到最简单的倒排索引。
在下面图中,“单词ID”一栏记录了每个单词的单词编号,第二栏是对应的单词,第三栏即每个单词对应的倒排列表。比如单词“谷歌”,其单词编号为1,倒排列表为{1,2,3,4,5},说明文档集合中每个文档都包含了这个单词。
之所以说上图所示倒排索引是最简单的,是因为这个索引系统只记载了哪些文档包含某个单词,而事实上,索引系统还可以记录除此之外的更多信息。
在单词对应的倒排列表中不仅记录了文档编号,还可以记载了单词频率信息(TF),即这个单词在某个文档中的出现次数,之所以要记录这个信息,是因为词频信息在搜索结果排序时,计算查询和文档相似度是很重要的一个计算因子,所以将其记录在倒排列表中,以方便后续排序时进行分值计算 实用的倒排索引还可以记载更多的信息,下图所示索引系统除了记录文档编号和单词频率信息外,额外记载了两类信息,即每个单词对应的“文档频率信息”(下图的第三栏)。
此外,除了上述信息,还可以在倒排列表中记录单词在某个文档出现的位置信息。
(1,<11>,1),(2,<7>,1),(3,< 3,9>,2)
#id是1的单词,出现1次,文档位置是11
#id是2的文档,出现1次,文档位置是7
#id是3的文档,出现2次,文档位置是3,9
上图所示倒排索引已经是一个非常完备的索引系统,实际搜索系统的索引结构基本如此,区别无非是采取哪些具体的数据结构来实现上述逻辑结构。
有了这个索引系统,搜索引擎可以很方便地响应用户的查询,比如用户输入查询词“Facebook”,搜索系统查找倒排索引,从中可以读出包含这个单词的文档,这些文档就是提供给用户的搜索结果,而利用单词频率信息、文档频率信息即可以对这些候选搜索结果进行排序,计算文档和查询的相似性,按照相似性得分由高到低排序输出,最后为用户展示出搜索结果。
参考文章
GET movie/_search
{
"query": {
"multi_match": {
"query": "chang",
"fields": ["actors", "title"]
}
}
}
相关度分数的计算使用的是TF/IDF算法(Term Frequency&Inverse Document Frequency)。
搜索内容:hello world
Hello, I love china.
Hello world,how are you!
所搜内容:hello world
hello, what are you doing?
I like the world.
hello 在索引的所有文档中出现了500次,world出现了100次
搜索内容:hello world
{“title”:“hello,what’s your name?”,“content”:{“owieurowieuolsdjflk”}}
{“title”:“hi,good morning?”,“content”:{“Ikjkljkj…world”}}
GET movie/_search
{
"query": {
"terms": {
"title.keyword": [
"英雄",
"Forrest Gump"
]
}
}
}
GET movie/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"rating": {
"order": "desc"
}
},
{
"title.keyword": {
"order": "asc"
}
}
]
}
GET movie/_search
{
"query": {
"range": {
"rating": {
"gte": 8,
"lte": 10
}
}
}
}
GET movie/_search
{
"query": {
"wildcard": {
"title": {
"value": "*gan"
}
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
GET movie/_search?scroll=1m
{
"query": {
"match_all": {}
},
"sort": ["movie_id"],
"size": 20
}
DELETE /_search/scroll/_all
GET /_search/scroll
{
"scroll":"1m",
"scroll_id" :"DnF1ZXJ5VGhlbkZldGNoAwAAAAAACg5sFkRUell5dGd3U2NxcFpUaXEyQkdhQUEAAAAAAAKAJxZWeGllTElWd1JIZWxwZnpEeW93dXVnAAAAAAACgCYWVnhpZUxJVndSSGVscGZ6RHlvd3V1Zw=="
}
注意: 如果Bool查询中包含至少一个 should 字句并且没有 must 或者 filter 字句, minimum_should_match 默认值为1,否则默认值为 0
GET movie/_search
{
"query": {
"bool": {
"must": [
{
"terms": {
"genre": ["动作","喜剧"]
}
},
{
"exists": {
"field": "introduction"
}
}
],
"must_not": [
{
"wildcard": {
"actors.keyword": "*黄晓明*"
}
}
],
"should": [
{
"wildcard": {
"actors.keyword": "*周润发*"
}
},
{
"wildcard": {
"actors.keyword": {
"value": "*成龙*"
}
}
}
],
"filter": [
{
"range": {
"releasedate": {
"gte": "1990/01/01"
}
}
},
{
"range": {
"rating": {
"gte": 6
}
}
}
],
"minimum_should_match": 1
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"min_rating": {
"min": {
"field": "rating"
}
},
"max_rating": {
"max": {
"field": "rating"
}
},
"avg_rating": {
"avg": {
"field": "rating"
}
},
"sum_rating": {
"sum": {
"field": "rating"
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"genre": {
"cardinality": {
"field": "genre"
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"stats_rting": {
"stats": {
"field": "rating"
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"per": {
"percentiles": {
"field": "rating",
"percents": [
1,
5,
25,
50,
75,
95,
99
]
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"NAME": {
"percentile_ranks": {
"field": "rating",
"values": [
7,
8
]
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"genre": {
"terms": {
"field": "genre",
"size": 20
},
"aggs": {
"NAME": {
"top_hits": {
"size": 2,
"sort": [
{
"releasedate": {
"order": "desc"
}
}
]
}
}
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"group_by_genre": {
"terms": {
"field": "genre",
"size": 50
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"rating_range": {
"range": {
"field": "rating",
"ranges": [
{
"key": "<6",
"from": 0,
"to": 6
},
{
"from": 6,
"to": 8
},
{
"from": 8,
"to": 10
}
]
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"date_range": {
"range": {
"field": "releasedate",
"format":"yyyy",
"ranges": [
{
"to":"1990"
},
{
"from": "1990",
"to": "2000"
},
{
"from": "2000"
}
]
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"by_rating": {
"histogram": {
"field": "rating",
"interval": 5
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"by_rating": {
"date_histogram": {
"field": "releasedate",
"interval": "year",
"format": "yyyy",
"extended_bounds": {
"min": "1991",
"max": "2100"
}
}
}
}
}
可以将数据分桶后再分桶或者进行分析
GET movie/_search
{
"size": 0,
"aggs": {
"group_by_genre": {
"terms": {
"field": "genre",
"size": 50,
"order": {
"rating.avg": "desc"
}
},
"aggs": {
"rating": {
"stats": {
"field": "rating"
}
}
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"group_by_genre": {
"terms": {
"field": "genre",
"size": 50,
"order": {
"_key": "asc"
}
},
"aggs": {
"by_rating": {
"range": {
"field": "rating",
"ranges": [
{
"to": 6
},
{
"from": 6,
"to": 8
},
{
"from": 8,
"to": 10
}
]
},
"aggs": {
"avg_rating": {
"avg": {
"field": "rating"
}
}
}
}
}
}
}
}
针对聚合分析的结果再次进行聚合分析
Pipeline 根据输出位置不同,分一下两类
GET movie/_search
{
"size": 0,
"aggs": {
"genre": {
"terms": {
"field": "genre",
"size": 20
},
"aggs": {
"avg_rating": {
"avg": {
"field": "rating"
}
}
}
},
"min_rating_by_genre":{
"min_bucket": {
"buckets_path": "genre>avg_rating"
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"year": {
"date_histogram": {
"field": "releasedate",
"interval": "year",
"format": "yyyy"
},
"aggs": {
"sum_rating": {
"sum": {
"field": "rating"
}
}
}
},
"avg_rating_per_year":{
"extended_stats_bucket": {
"buckets_path": "year>sum_rating"
}
}
}
}
GET movie/_search
{
"size": 0,
"aggs": {
"year": {
"date_histogram": {
"field": "releasedate",
"interval": "year",
"format": "yyyy"
},
"aggs": {
"avg_rating": {
"avg": {
"field": "rating",
"missing": 0
}
},
"cumulative_avg":{
"cumulative_sum": {
"buckets_path": "avg_rating"
}
}
}
}
}
}