{ "title": "射雕英雄传", "people": ["郭靖", "黄蓉", "杨康", "穆念慈"], "year": 1962, "text": "该小说历史背景突出,场景纷繁,气势宏伟,具有鲜明的“英雄史诗”风格;在人物创造与情节安排上,它 打破了传统武侠小说一味传奇,将人物作为情节附庸的模式,坚持以创造个性化的人物形象为中心,坚持人物统帅故事,按 照人物性格的发展需要及其内在可能性、必然性来设置情节,从而使这部小说达到了事虽奇人却真的妙境。", "kongfu": ["蛤蟆功", "黯然销魂掌", "降龙十八掌", "双手互搏术"] } //样本二 { "title": "天龙八部", "people": ["段誉", "萧峰", "虚竹", "丁春秋"], "year": 1962, "text": "这部小说以宋哲宗时代为背景,通过宋、辽、大理、西夏、吐蕃等王国之间的武林恩怨和民族矛盾,从哲学 的高度对人生和社会进行审视和描写,展示了一幅波澜壮阔的生活画卷。其故事之离奇曲折、涉及人物之众多、历史背景之 广泛、武侠战役之庞大、想象力之丰富当属“金书”之最。作品风格宏伟悲壮,是一部写尽人性、悲剧色彩浓厚的史诗巨 著。", "kongfu": ["六脉神剑", "千蛛万毒手", "九阴白骨爪", "化骨绵掌"] } //样本三 { "title": "笑傲江湖", "people": ["令狐冲", "任盈盈", "岳灵珊", "林平之"], "year": 1960, "text": "福建林远图以七十二路辟邪剑法称雄武林,创立福威镖局,驰骋江湖。远图死后,子孙无能,四方豪杰纷纷 觊觎辟邪剑谱。福威镖局总镖头林震南一门被青城派屠戮殆尽。遗孤林平之拜投华山派掌门君子剑岳不群门下,一心学艺报 仇。", "kongfu": ["独孤九剑", "辟邪剑法", "葵花宝典", "七伤拳"] } //样本四 { "title": "倚天屠龙记", "people": ["张无忌", "赵敏", "张翠山", "殷素素"], "year": 1961,1.2创建索引 在ElasticSearch索引中,对应于CRUD中的“创建”和“更新” - 如果对具有给定类型的文档进行索引,并且要插入原先不 存在的ID。 如果具有相同类型和ID的文档已存在,则会被覆盖。 要索引第一个JSON对象,我们对REST API创建一个PUT请求到一个由索引名称,类型名称和ID组成的URL。 "text": "少林寺觉远禅师看护《楞伽经》不力,导致经书被尹克西和潇湘子盗走。潇湘子和尹克西互相猜忌残杀,临 终之前幡然醒悟,委托何足道向觉远转达经书的下落。何足道接受委托,并向少林寺发出挑战。适逢郭靖、黄蓉的女儿郭襄 前往少林寺寻找杨过,从罗汉掌首座无色禅师处得知何足道挑战少林武功的消息,遂在约定日子只身前往观战。觉远禅师的 弟子张君宝在与何足道一战之中暴露了偷学武功的事实,犯了寺规,受到少林寺众僧的围攻。于是觉远携张君宝、郭襄突出 重围,却在途中圆寂。张君宝与郭襄分手之后,只身前往武当山修学觉远生前传授的九阳真经,并深得道家冲虚圆通之功的 精髓,加以融会贯通,创出了武当一派武功,遂自号三丰。", "kongfu": ["太极剑", "吸星大法", "七伤拳", "玄冥神掌"] }http : //localhost:9200/books/jinyong/1 // 创建 movies 下金庸先生的作品 curl - XPUT "http://localhost:9200/books/jinyong/1" // 创建 << 射雕英雄传 >> 作品为索引 curl - XPUT "http://localhost:9200/books/jinyong/2" // 创建 << 天龙八部 >> 作品为索引 curl - XPUT "http://localhost:9200/books/jinyong/3" // 创建 << 笑傲江湖 >> 作品为索引 curl - XPUT "http://localhost:9200/books/jinyong/4" // 创建 << 倚天屠龙记 >> 作品为索引 // 执行结果分别为:
{ "_index": "books", "_type": "jinyong", "_id": "1",//文档ID "_version": 1,//版本号(_version)可用于跟踪文档已编入索引的次数 "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 0, "_primary_term": 1 }//... 字段 注释
_ 1.3 文本的搜索 1.3.1 搜索所有索引和所有类型 在实际场景中大家一定会遇到对文本中的单词进行搜索如:在一本书中找某一个人物,在日志文件中找对应的关键字 等等,那么下面解释下 es 在这些文章中的搜索的应用 如何使用 http://localhost:9200/_search - 搜索所有索引和所有类型。 // 这边以全文搜索小说为例创建请求参数
{ "query": { "query_string": { "query": "小说" } } } 响应结果: { "took": 18, "timed_out": false, "_shards": { "total": 7, "successful": 7, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 2, "relation": "eq" }, "max_score": 2.2695534, "hits": [{ "_index": "books", "_type": "jinyong", "_id": "1", "_score": 2.2695534, "_source": { "title": "射雕英雄传", "people": [ "郭靖", "黄蓉", "杨康", "穆念慈" ], "year": 1962, "text": "该小说历史背景突出,场景纷繁,气势宏伟,具有鲜明的“英雄史诗”风格;在人物创 造与情节安排上,它打破了传统武侠小说一味传奇,将人物作为情节附庸的模式,坚持以创造个性化的人物形象为中心,坚 持人物统帅故事,按照人物性格的发展需要及其内在可能性、必然性来设置情节,从而使这部小说达到了事虽奇人却真的妙 境。", "kongfu": [ "蛤蟆功", "黯然销魂掌", "降龙十八掌", "双手互搏术" ] } }, { "_index": "books", "_type": "jinyong", "_id": "2", "_score": 1.4682897, "_source": { "title": "天龙八部", "people": [ "段誉", "萧峰", "虚竹", "丁春秋" ], "year": 1962, "text": "这部小说以宋哲宗时代为背景,通过宋、辽、大理、西夏、吐蕃等王国之间的武林恩 怨和民族矛盾,从哲学的高度对人生和社会进行审视和描写,展示了一幅波澜壮阔的生活画卷。其故事之离奇曲折、涉及人 物之众多、历史背景之广泛、武侠战役之庞大、想象力之丰富当属“金书”之最。作品风格宏伟悲壮,是一部写尽人性、悲剧 色彩浓厚的史诗巨著。", "kongfu": [ "六脉神剑", "千蛛万毒手", "九阴白骨爪", "化骨绵掌" ] } }
1.3.2 指定搜索的字段 如何使用 http://localhost:9200/_search - 搜索所有索引和所有类型。 } } // 这边以全文搜索小说为例创建请求参数
{ "query": { "query_string": { "query": "射雕英雄传", "fields": ["title"] } } } //响应结果: { "took": 3, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 5.758131, "hits": [1.3.3 过滤与近似匹配 因为在索引中有四部小说在 kongfu 字段 ( 从类别字段 ) 中包含 “ 七伤拳 ” ,所以得到了上述查询的 2 个命中。 现在,想 象一下,如果我们想限制不是 1961 年发布的电影。要做到这点,需要应用一个过滤器,要求 “ year ” 字段不等于 1961 。
{ "_index": "books", "_type": "jinyong", "_id": "1", "_score": 5.758131, "_source": { "title": "射雕英雄传", "people": [ "郭靖", "黄蓉", "杨康", "穆念慈" ], "year": 1962, "text": "该小说历史背景突出,场景纷繁,气势宏伟,具有鲜明的“英雄史诗”风格;在人物创 造与情节安排上,它打破了传统武侠小说一味传奇,将人物作为情节附庸的模式,坚持以创造个性化的人物形象为中心,坚 持人物统帅故事,按照人物性格的发展需要及其内在可能性、必然性来设置情节,从而使这部小说达到了事虽奇人却真的妙 境。", "kongfu": [ "蛤蟆功", "黯然销魂掌", "降龙十八掌", "双手互搏术" ] } } ] } } { "query": { "bool": { "must": [ { "match": { "kongfu": "七伤拳" } } ], "must_not": [ { "match": { "year": 1961 } } ] }} } //响应结果 { "took": 3, "timed_out": false, "_shards": { "total": 8, "successful": 8, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 2.1470044, "hits": [ { "_index": "books", "_type": "jinyong", "_id": "3", "_score": 2.1470044, "_source": { "title": "笑傲江湖", "people": [ "令狐冲", "任盈盈", "岳灵珊", "林平之" ], "year": 1960, "text": "福建林远图以七十二路辟邪剑法称雄武林,创立福威镖局,驰骋江湖。远图死后,子 孙无能,四方豪杰纷纷觊觎辟邪剑谱。福威镖局总镖头林震南一门被青城派屠戮殆尽。遗孤林平之拜投华山派掌门君子剑岳 不群门下,一心学艺报仇。", "kongfu": [ "独孤九剑", "辟邪剑法", "葵花宝典", "七伤拳" ] } } ] } }布尔查询中每个 must , should,must_not 都被称为查询子句。每个 must 或者 should 查询子句中的条件都会影响 文档的相关得分。得分越高,文档跟搜索条件匹配得越好。默认情况下, Elasticsearch 返回的文档会根据相关性算 分倒序排列。 must_not 子句中认为是过滤条件。它会过滤返回结果,但不会影响文档的相关性算分,你还可以明确指定任意过滤 条件去筛选结构化数据文档。 // 请求搜索 year 在 1961~ 1970 (包括 1961 ) 之间的所有书籍
{ "query": { "bool": { "must": { "match_all": {} }, "filter": { "range": { "year": { "gte": 1961, "lte": 1970 } } } } } } //响应结果: { "took": 2, "timed_out": false, "_shards": { "total": 8, "successful": 8, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 5, "relation": "eq" }, "max_score": 1.0, "hits": [ { "_index": "books", "_type": "jinyong", "_id": "1", "_score": 1.0, "_source": { "title": "射雕英雄传", "people": [ "郭靖", "黄蓉", "杨康", "穆念慈"], "year": 1962, "text": "该小说历史背景突出,场景纷繁,气势宏伟,具有鲜明的“英雄史诗”风格;在人物创 造与情节安排上,它打破了传统武侠小说一味传奇,将人物作为情节附庸的模式,坚持以创造个性化的人物形象为中心,坚 持人物统帅故事,按照人物性格的发展需要及其内在可能性、必然性来设置情节,从而使这部小说达到了事虽奇人却真的妙 境。", "kongfu": [ "蛤蟆功", "黯然销魂掌", "降龙十八掌", "双手互搏术" ] } }, { "_index": "books", "_type": "jinyong", "_id": "2", "_score": 1.0, "_source": { "title": "天龙八部", "people": [ "段誉", "萧峰", "虚竹", "丁春秋" ], "year": 1962, "text": "这部小说以宋哲宗时代为背景,通过宋、辽、大理、西夏、吐蕃等王国之间的武林恩 怨和民族矛盾,从哲学的高度对人生和社会进行审视和描写,展示了一幅波澜壮阔的生活画卷。其故事之离奇曲折、涉及人 物之众多、历史背景之广泛、武侠战役之庞大、想象力之丰富当属“金书”之最。作品风格宏伟悲壮,是一部写尽人性、悲剧 色彩浓厚的史诗巨著。", "kongfu": [ "六脉神剑", "千蛛万毒手", "九阴白骨爪", "化骨绵掌" ] } }, { "_index": "books", "_type": "jinyong", "_id": "4", "_score": 1.0, "_ignored": [ "text.keyword" ], "_source": { "title": "倚天屠龙记", "people": [ "张无忌", "赵敏",1.4 邻近匹配 1.4.1match 与 match_phrase curl -XGET " http://localhost:9200/books/_search "// 创建 << 商品 >> 名称信息的索引。 虽然邻近查询很有用, 但是所有词条都出现在文档的要求过于严格了。 同样的问题: 如果七个词条中有六个匹配, 那么这个文档对用户而言就已经足够相关了, 但是 match_phrase 查 询可能会将它排除在外。 我们可以将一个简单的 match 查询作为一个 must 子句。 这个查询将决定哪些文档需要被包含到结果集中。 我们 可以用 minimum_should_match 参数去除长尾。 然后我们可以以 should 子句的形式添加更多特定查询。 每一个 匹配成功的都会增加匹配文档的相关度。 // demo
{ "took": 3, "timed_out": false, "_shards": { "total": 1, "张翠山", "殷素素" ], "year": 1961, "text": "少林寺觉远禅师看护《楞伽经》不力,导致经书被尹克西和潇湘子盗走。潇湘子和尹 克西互相猜忌残杀,临终之前幡然醒悟,委托何足道向觉远转达经书的下落。何足道接受委托,并向少林寺发出挑战。适逢 郭靖、黄蓉的女儿郭襄前往少林寺寻找杨过,从罗汉掌首座无色禅师处得知何足道挑战少林武功的消息,遂在约定日子只身 前往观战。觉远禅师的弟子张君宝在与何足道一战之中暴露了偷学武功的事实,犯了寺规,受到少林寺众僧的围攻。于是觉 远携张君宝、郭襄突出重围,却在途中圆寂。张君宝与郭襄分手之后,只身前往武当山修学觉远生前传授的九阳真经,并深 得道家冲虚圆通之功的精髓,加以融会贯通,创出了武当一派武功,遂自号三丰。", "kongfu": [ "太极剑", "吸星大法", "七伤拳", "玄冥神掌" ] } } ] } } { "query": { "match": { "text": "在人物创造与情节安排上" } } }"successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 4, "relation": "eq" }, "max_score": 14.441122, "hits": [ { "_index": "books", "_type": "jinyong", "_id": "1", "_score": 14.441122, "_source": { "title": "射雕英雄传", "people": [ "郭靖", "黄蓉", "杨康", "穆念慈" ], "year": 1962, "text": "该小说历史背景突出,场景纷繁,气势宏伟,具有鲜明的“英雄史诗”风格;在人物创造 与情节安排上,它打破了传统武侠小说一味传奇,将人物作为情节附庸的模式,坚持以创造个性化的人物形象为中心,坚持人 物统帅故事,按照人物性格的发展需要及其内在可能性、必然性来设置情节,从而使这部小说达到了事虽奇人却真的妙境。", "kongfu": [ "蛤蟆功", "黯然销魂掌", "降龙十八掌", "双手互搏术" ] } }, { "_index": "books", "_type": "jinyong", "_id": "4", "_score": 2.0315528, "_ignored": [ "text.keyword" ], "_source": { "title": "倚天屠龙记", "people": [ "张无忌", "赵敏", "张翠山", "殷素素" ], "year": 1961,"text": "少林寺觉远禅师看护《楞伽经》不力,导致经书被尹克西和潇湘子盗走。潇湘子和尹克 西互相猜忌残杀,临终之前幡然醒悟,委托何足道向觉远转达经书的下落。何足道接受委托,并向少林寺发出挑战。适逢郭 靖、黄蓉的女儿郭襄前往少林寺寻找杨过,从罗汉掌首座无色禅师处得知何足道挑战少林武功的消息,遂在约定日子只身前往 观战。觉远禅师的弟子张君宝在与何足道一战之中暴露了偷学武功的事实,犯了寺规,受到少林寺众僧的围攻。于是觉远携张 君宝、郭襄突出重围,却在途中圆寂。张君宝与郭襄分手之后,只身前往武当山修学觉远生前传授的九阳真经,并深得道家冲 虚圆通之功的精髓,加以融会贯通,创出了武当一派武功,遂自号三丰。", "kongfu": [ "太极剑", "吸星大法", "七伤拳", "玄冥神掌" ] } }, { "_index": "books", "_type": "jinyong", "_id": "2", "_score": 1.8561981, "_source": { "title": "天龙八部", "people": [ "段誉", "萧峰", "虚竹", "丁春秋" ], "year": 1962, "text": "这部小说以宋哲宗时代为背景,通过宋、辽、大理、西夏、吐蕃等王国之间的武林恩怨 和民族矛盾,从哲学的高度对人生和社会进行审视和描写,展示了一幅波澜壮阔的生活画卷。其故事之离奇曲折、涉及人物之 众多、历史背景之广泛、武侠战役之庞大、想象力之丰富当属“金书”之最。作品风格宏伟悲壮,是一部写尽人性、悲剧色彩浓 厚的史诗巨著。", "kongfu": [ "六脉神剑", "千蛛万毒手", "九阴白骨爪", "化骨绵掌" ] } }, { "_index": "books", "_type": "jinyong", "_id": "3", "_score": 0.4352452, "_source": { "title": "笑傲江湖", "people": [ "令狐冲", "任盈盈", "岳灵珊", "林平之" ],"year": 1960, "text": "福建林远图以七十二路辟邪剑法称雄武林,创立福威镖局,驰骋江湖。远图死后,子孙 无能,四方豪杰纷纷觊觎辟邪剑谱。福威镖局总镖头林震南一门被青城派屠戮殆尽。遗孤林平之拜投华山派掌门君子剑岳不群 门下,一心学艺报仇。", "kongfu": [ "独孤九剑", "辟邪剑法", "葵花宝典", "七伤拳" ] } } ] } }同学可以看到是四条数据那是因为 Elasticsearch 将 " 在人物创造与情节安排上 " 做了分词查询所以我们的查询结果中可 以查询到,所以这种查询方式我们称为全文查询。当然如果同学们需要精确匹配可以使用 match_phrase 。 1.4.2highlight 从字面上意思大家都应该能够理解其中意思 " 高亮 " 这种在实际应用也是在各大收索引擎中是应用非常多的。我们看下 面截图 : 这就是在 highlight 在大数据时代中搜索中的应用,那么在 Elasticsearch 怎么去做这样子的工作。
{ "took": 54, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 3.4595068, "hits": [ {"_index": "books", "_type": "jinyong", "_id": "1", "_score": 3.4595068, "_source": { "title": "射雕英雄传", "people": [ "郭靖", "黄蓉", "杨康", "穆念慈" ], "year": 1962, "text": "该小说历史背景突出,场景纷繁,气势宏伟,具有鲜明的“英雄史诗”风格;在人物创造 与情节安排上,它打破了传统武侠小说一味传奇,将人物作为情节附庸的模式,坚持以创造个性化的人物形象为中心,坚持人 物统帅故事,按照人物性格的发展需要及其内在可能性、必然性来设置情节,从而使这部小说达到了事虽奇人却真的妙境。", "kongfu": [ "蛤蟆功", "黯然销魂掌", "降龙十八掌", "双手互搏术" ] }, "highlight": { "kongfu": [ "蛤蟆功" ] } } ] } } 1.4.3聚合查询 在Elasticsearch中eggs表示聚合 *** 作: { "aggs": {//聚合 *** 作 "year_group": {//分组名称 "terms": {//分组 "field": "year"//分组字段 } } }, "size": 0//去掉原始数据 } //分组响应结果 { "took": 28, "timed_out": false,"_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 4, "relation": "eq" }, "max_score": null, "hits": [] }, "aggregations": { "year_group": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": 1962, "doc_count": 2 }, { "key": 1960, "doc_count": 1 }, { "key": 1961, "doc_count": 1 } ] } } } 聚合里面还有其他什么统计方式呢?? 1.4.4综合查询中的使用 虽然邻近查询很有用, 但是所有词条都出现在文档的要求过于严格了。 同样的问题: 如果七个词条中有六个匹配, 那么这个文档对用户而言就已经足够相关了, 但是 match_phrase 查 询可能会将它排除在外。 我们可以将一个简单的 match 查询作为一个 must 子句。 这个查询将决定哪些文档需要被包含到结果集中。 我们 可以用 minimum_should_match 参数去除长尾。 然后我们可以以 should 子句的形式添加更多特定查询。 每一个 匹配成功的都会增加匹配文档的相关度。 { "query": { "bool": {"must": { "match": { "kongfu": { "query": "独孤九剑", "minimum_should_match": "30%" } } }, "should": { "match_phrase": { "kongfu": { "query": "太极剑", "slop": 50 } } } } } } //响应结果 { "took": 12, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 3, "relation": "eq" }, "max_score": 3.703123, "hits": [ { "_index": "books", "_type": "jinyong", "_id": "3", "_score": 3.703123, "_source": { "title": "笑傲江湖", "people": [ "令狐冲", "任盈盈", "岳灵珊", "林平之" ], "year": 1960, "text": "福建林远图以七十二路辟邪剑法称雄武林,创立福威镖局,驰骋江湖。远图死后,子孙 无能,四方豪杰纷纷觊觎辟邪剑谱。福威镖局总镖头林震南一门被青城派屠戮殆尽。遗孤林平之拜投华山派掌门君子剑岳不群门下,一心学艺报仇。", "kongfu": [ "独孤九剑", "辟邪剑法", "葵花宝典", "七伤拳" ] } }, { "_index": "books", "_type": "jinyong", "_id": "4", "_score": 3.3087118, "_ignored": [ "text.keyword" ], "_source": { "title": "倚天屠龙记", "people": [ "张无忌", "赵敏", "张翠山", "殷素素" ], "year": 1961, "text": "少林寺觉远禅师看护《楞伽经》不力,导致经书被尹克西和潇湘子盗走。潇湘子和尹克 西互相猜忌残杀,临终之前幡然醒悟,委托何足道向觉远转达经书的下落。何足道接受委托,并向少林寺发出挑战。适逢郭 靖、黄蓉的女儿郭襄前往少林寺寻找杨过,从罗汉掌首座无色禅师处得知何足道挑战少林武功的消息,遂在约定日子只身前往 观战。觉远禅师的弟子张君宝在与何足道一战之中暴露了偷学武功的事实,犯了寺规,受到少林寺众僧的围攻。于是觉远携张 君宝、郭襄突出重围,却在途中圆寂。张君宝与郭襄分手之后,只身前往武当山修学觉远生前传授的九阳真经,并深得道家冲 虚圆通之功的精髓,加以融会贯通,创出了武当一派武功,遂自号三丰。", "kongfu": [ "太极剑", "吸星大法", "七伤拳", "玄冥神掌" ] } }, { "_index": "books", "_type": "jinyong", "_id": "2", "_score": 1.0055228, "_source": { "title": "天龙八部", "people": [ "段誉", "萧峰", "虚竹", "丁春秋" ],"year": 1962, "text": "这部小说以宋哲宗时代为背景,通过宋、辽、大理、西夏、吐蕃等王国之间的武林恩怨 和民族矛盾,从哲学的高度对人生和社会进行审视和描写,展示了一幅波澜壮阔的生活画卷。其故事之离奇曲折、涉及人物之 众多、历史背景之广泛、武侠战役之庞大、想象力之丰富当属“金书”之最。作品风格宏伟悲壮,是一部写尽人性、悲剧色彩浓 厚的史诗巨著。", "kongfu": [ "六脉神剑", "千蛛万毒手", "九阴白骨爪", "化骨绵掌" ] } } ] } }1.5 映射分词查询 在实际应用中会对我们的文本数据进行相关的管理,有些词可能会进行分词有些可能为关键词不能作为分词信息。 首先我们这边先来对我们的商品信息创建它的: 首先我们创建一个商品的索引: curl -XPUT " http://localhost:9200/product "// 创建 << 商品 >> 名称信息的索引 // 响应结果:
{ "acknowledged": true, "shards_acknowledged": true, "index": "product" } curl -XPUT "http://localhost:9200/product/_mapping"//创建<<商品>>信息的结构信息(商品名称,商品价格,商品 库存)。 { "properties": {//对数据进行约束 "name": { "type": "text",//文本可分词 "index": true//可索引 }, "price": { "type": "keyword",//关键词 "index": true//可索引 }, "stock": { "type": "keyword",//关键词"index": false//不可索引 } } }// 响应结果:
{ "acknowledged": true } //那么我们现在创建了商品为索引的结构体信息那么,现在我们对product,来创建信息。 curl -XPUT "http://localhost:9200/product/_create/10001" //创建商品信息 { "name": "我是价格为50元的衣服我哦还有100件", "price": 50, "stock": 100 } { "_index": "product", "_type": "_doc", "_id": "10001", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 0, "_primary_term": 1 } 接下来我们来看下查询: curl -XPUT "http://localhost:9200/product/_search" //查询名称包含衣服的数据 { "query":{ "match": { "name":"衣服" } } } { "took": 1030, "timed_out": false,"_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 0.5753642, "hits": [ { "_index": "product", "_type": "_doc", "_id": "10001", "_score": 0.5753642, "_source": { "name": "我是价格为50元的衣服我哦还有100件", "price": 50, "stock": 100 } } ] } }keyword 的设置这里根据类推,这里同学们思考下会是什么样子的结构查询。 2. 基于 Elasticsearch 分析用户行为 2.1 背景介绍 根据用户输入和筛选条件进行搜索后,有时返回的是无结果或者结果很少的情况,为了提升用户搜索体验,需要能够 给用户推荐一些相关的搜索词,比如用户搜索【张无忌】时没有找到相关的 任务,可以推荐搜索【玄冥神掌】、 【七伤拳】等关键词。 2.2 设计思路 首先需要分析搜索无结果或者结果过少可能的原因,我总结了一下,主要包括主要可能: 1. 搜索的关键词在本网不存在,比如【金毛狮王】; 2. 搜索的关键词在本网的文本很少,比如【小说】; 3. 搜索的关键词拼写有问题,比如把【九阴白骨爪】写成了【九荫白骨抓】; 那么针对以上情况,可以采用以下方式进行处理: 1. 搜索的关键词在本网不存在,可以通过爬虫的方式获取相关知识,然后根据 搜索建议词 去提取,比如去百度百 科的【金毛狮王】词条里就能提取出【七伤拳】、【张无忌】和【谢逊】等关键词;当然基于爬虫的知识可能 存在偏差,此时需要能够有人工审核或人工更正的部分; 2. 搜索的关键词在本网的商品很少,有两种解决思路,一种是通过方式 1 的爬虫去提取关键词,另外一种是通过返 回商品的信息去聚合出关键词,如书籍、武功、风格、标签等,这里我们采用的是后者(在测试后发现后者效 果更佳); 3. 搜索的关键词拼写有问题,这就需要 拼写纠错 出场了,先纠错然后根据纠错后的词去提供搜索推荐; 4. 搜索的关键词过多,有两种解决思路,一种是识别关键词的类型,如是品牌、品类、风格还是性别,然后通过 一定的组合策略来实现搜索推荐;另外一种则是根据用户的输入到搜索建议词里去匹配,设置最小匹配为一个 匹配到一个 Term 即可,这种方式实现比较简单而且效果也不错,所以我们采用的是后者。 所以,我们在实现搜索推荐的核心是之前讲到的搜索建议词,它提供了本网主要的关键词,另外一个很重要的是它本 身包含了 关联作品的属性 ,这样就可以保证推荐给用户的关键词是可以搜索出结果的。 这里列取相关字段的索引:
{ "mappings": { "suggest": { "properties": { "keyword": { "fields": { "keyword": { "type": "string", "index": "not_analyzed" }, "keyword_lowercase": { "type": "string", "analyzer": "lowercase_keyword" }, "keyword_ik": { "type": "string", "analyzer": "ik_smart" }, "keyword_pinyin": { "type": "string", "analyzer": "pinyin_analyzer" }, "keyword_first_py": { "type": "string", "analyzer": "pinyin_first_letter_keyword_analyzer" } }, "type": "multi_field" }, "type": { "type": "long" }, "weight": { "type": "long" }, "count": { "type": "long"} } } } } 书籍数据索引 { "mappings": { "books": { "properties": { "jinyong": { "type": "long" }, "title": { "type": "string", "analyzer": "ik_smart" }, "people": { "type": "string", "analyzer": "ik_smart" }, "kongfu": { "type": "string", "analyzer": "ik_smart" } } } } } 关键词映射索引 主要就是source和dest直接的映射关系。 PUT /conversion_index { "mappings": { "conversion": { "properties": { "source": { "type": "string", "analyzer": "lowercase_keyword" }, "dest": { "type": "string", "index": "not_analyzed" } } }} }2.3 搜索建议实现 在我们的搜索建议实现里,主要考虑了建议词的来源、匹配、排序、关联的作品名称和拼写纠错。 SuggestionDiscovery SuggestionDiscovery 的职责是发现建议词; 建议词的来源可以是商品的作品名称、作者名称、作品标签、作品名称的高频词、热搜词,也可以是一些组合 词,比如 “ 分类 + 性别 ” 和 “ 分类 + 标签 ” ,还可以是一些自定义添加的词; 建议词维护的时候需要考虑去重,比如 “ 倚天屠龙记 ” 和 “ 倚天屠龙 记 ” 应该是相同的, “ 金毛狮王 ” 和 “ 谢逊 ” 也应该 是相同的; 由于建议词的来源通常比较稳定,所以执行的周期可以比较长一点,比如每周一次; SuggestionCounter SuggestionCounter 的职责是获取建议词关联的作品,如果需要可以进行一些聚合 *** 作,比如聚合分类和标 签; SuggestionCounter 的实现的时候由于要真正地调用搜索接口,应该尽量避免对用户搜索的影响,比如在凌晨 执行并且使用单线程调用; 为了提升效率,应该使用 Elasticsearch 的 Multi Search 接口批量进行 count ,同时批量更新数据库里建议词的 count 值; 由于 SuggestionCounter 是比较耗资源的,可以考虑延长执行的周期,但是这可能会带来 count 值与实际搜索时 误差较大的问题,这个需要根据实际情况考虑; SuggestionIndexRebuiler SuggestionIndexRebuiler 的职责是负责重建索引; 考虑到用户的搜索习惯,可以使用 Multi-fifields 来给建议词增加多个分析器。比如对于【小说 文章】的建议词使 用 Multi-fifields 增加不分词字段、拼音分词字段、拼音首字母分词字段、分词字段,这样输入【金庸】和 【 jinyong 】都可以匹配到该建议词; 重建索引时通过是通过 bulk 批量添加到临时索引中,然后通过别名来更新; 重建索引的数据依赖于 SuggestionCounter ,因此其执行的周期应该与 SuggestionCounter 保持一致; SuggestionService SuggestionService 是真正处于用户搜索建议的服务类; 通常的实现是先到缓存中查询是否能匹配到缓存记录,如果能匹配到则直接返回;否则的话调用 Elasticsearch 的 Prefifix Query 进行搜索,由于我们在重建索引的时候定义了 Multi-fifields ,在搜索的时候应该用 boolQuery 来 处理;如果此时 Elasticsearch 返回不为空的结果数据,那么加入缓存并返回即可; 3.Elasticsearch 应用 3.1 使用 Elasticsearch 作为我们后台的文本搜索工具 索引擎是部署在成熟的数据存储的顶部,以提供快速且相关的搜索能力。这是因为早期的搜索引擎不能提供耐用的存 储或其他经常需要的功能,如统计。 Elasticsearch 是提供持久存储、统计等多项功能的现代搜索引擎。 如果你开始一个新项目,我们建议您考虑使用 Elasticsearch 作为唯一的数据存储,以帮助保持你的设计尽可能简单。 此种场景不支持包含频繁更新、事务 ( transaction )的 *** 作。 举例如下:新建一个博客系统使用 es 作为存储。 1. 我们可以向 ES 提交新的大量文本信息; 2. 使用 ES 检索、搜索、统 计数据。 ES 作为存储的优势: 如果一台服务器出现故障时会发生什么?你可以通过复制 数据到不同的服务器以达到容错的目 的。 注意: 整体架构设计时,需要我们权衡是否有必要增加额外的存储。 3.2 在现有系统中增加 elasticsearch 由于 ES 不能提供存储的所有功能,一些场景下需要在现有系统数据存储的基础上新增 ES 支持。 举例 1 : ES 不支持事务、复杂的关系(至少 1.X 版本不支持, 2.X 有改善,但支持的仍然不好),如果你的系统中需要 上述特征的支持,需要考虑在原有架构、原有存储的基础上的新增 ES 的支持。 举例 2 :如果你已经有一个在运行的复杂的系统,你的需求之一是在现有系统中添加检索服务。一种非常冒险的方式 是重构系统以支持 ES 。而相对安全的方式是:将 ES 作为新的组件添加到现有系统中。 如果你使用了如下图所示的 SQL 数据库和 ES 存储,你需要找到一种方式使得两存储之间实时同步。需要根据数据的组成、数据库选择对应的同步 插件。可供选择的插件包括: 1 ) mysql 、 oracle 选择 logstash-input-jdbc 插件。 2 ) mongo 选择 mongo connector 工具。 假设你的在线零售商店的产品信息存储在 SQL 数据库中。 为了快速且相关的搜索,你安装 Elasticsearch 。 为了索引 数据,您需要部署一个同步机制,该同步机制可以是 Elasticsearch 插件或你建立一个自定义的服务。此同步机制可以 将对应于每个产品的所有数据和索引都存储在 Elasticsearch ,每个产品作为一个 document 存储(这里的 document 相当于关系型数据库中的一行 /row 数据)。 当在该网页上的搜索条件中输入 “ 用户的类型 ” ,店面网络应用程序通过 Elasticsearch 查询该信息。 Elasticsearch 返回 符合标准的产品 documents ,并根据你喜欢的方式来分类文档。 排序可以根据每个产品的被搜索次数所得到的相关 分数,或任何存储在产品 document 信息,例如:最新最近加入的产品、平均得分,或者是那些插入或更新信息。 所 以你可以只使用 Elasticsearch 处理搜索。这取决于同步机制来保持 Elasticsearch 获取最新变化。 3.3 使用 elasticsearch 和现有的工具 在工作中我们需要把数据展现出来,就能通过 elasticssearch 完成一项工作。很多工具都可以与 Elasticsearch 一起工 作,我们没有必要在去编写它的可视化工具。 需要部署一个大规模的日志框架存储,搜索,并分析了大量的事件。 如果处理处理日志和输出到 Elasticsearch ,您 可以使用日志记录工具。 1.rsyslog ( www.rsyslog.com ), 2.Logstash ( www.elastic.co/products/logstash ) 3.Apache Flume ( http://flflume.apache.org )。 可视化工具 : Kibana ( www.elastic.co/cn/kibana )。 在开发工具中我们也是可以用来做我们的数据调试: 3.4 使用 elasticsearch 解决订单数据 显然只通过 DB 来支撑大量的查询是不可取的,同时对于一些复杂的查询, Mysql 支持得不够友好,所以 Elasticsearch 分布式搜索储存集群的引入,就是为了解决订单数据的存储与搜索的问题。 对订单模型进行抽象和分类,将常用搜索字段和基础属性字段剥离。 DB 做分库分表,存储订单详情; Elasticsearch 存储搜素字段。 为了解决商品订单数据存储,复杂查询,我们看下图:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)