场景:数据库中按照某个字段排序,sql只需写order by 字段名即可,如果es对一个text field
进行排序,es中无法排序。因为文档入倒排索引表时,分词存入,es无法知道此字段的真实值。这样的结果往往不准确,因为分词后是多个单词,再排序就不是我们想要的结果了。
通常有两种解决办法:
fielddata:true
,按照第一个分词进行字典序排序。这种方式也不是很准确,因为只是按照第一个分词进行排序,后续的分词不会参与排序。fielddata:true的排序是对text内部分词结果进行排序之后再进行外部排序的,效率低不推荐使用;样例如下:
首先建立索引
PUT /website { "mappings": { "properties": { "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "content": { "type": "text", "fielddata": true }, "post_date": { "type": "date" }, "author_id": { "type": "long" } } } }
插入数据
PUT /website/_doc/1 { "title": "first article", "content": "this is my second article", "post_date": "2019-01-01", "author_id": 110 } PUT /website/_doc/2 { "title": "second article", "content": "this is my second article", "post_date": "2019-01-01", "author_id": 110 } PUT /website/_doc/3 { "title": "third article", "content": "this is my third article", "post_date": "2019-01-02", "author_id": 110 }
搜索,按照整个title的值进行排序
GET /website/_search { "query": { "match_all": {} }, "sort": [ { "title.keyword": { "order": "desc" } } ] }
结果如下:
可以看出是以title的内容进行排序
然后再看下"fielddata": true这种情况,对content进行排序
GET /website/_search { "query": { "match_all": {} }, "sort": [ { "content": { "order": "desc" } } ] }
结果如下:
结果是以分词后的第一个单词进行排序,排序结果不准确,所以不推荐使用。
场景:下载某一个索引中1亿条数据,到文件或是数据库。
不能一下全查出来,这样会造成系统内存溢出。所以使用scoll滚动搜索技术,一批一批查询。scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,如果这个期间数据变更,是不会让用户看到的。每次发送scroll请求,我们还需要指定一个scoll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了。
假如有三亿条数据,这里实际只有3条
添加测试数据
PUT /book/_doc/1 { "name": "Bootstrap开发", "description": "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。", "studymodel": "201002", "price": 38.6, "timestamp": "2019-08-25 19:11:35", "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg", "tags": [ "bootstrap", "dev" ] } PUT /book/_doc/2 { "name": "java编程思想", "description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。", "studymodel": "201001", "price": 68.6, "timestamp": "2019-08-25 19:11:35", "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg", "tags": [ "java", "dev" ] } PUT /book/_doc/3 { "name": "spring开发基础", "description": "spring 在java领域非常流行,java程序员都在用。", "studymodel": "201001", "price": 88.6, "timestamp": "2019-08-24 19:11:35", "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg", "tags": [ "spring", "java" ] }
搜索
GET /book/_search?scroll=1m { "query": { "match_all": {} }, "size": 1 }
首先获取第一批次的数据,这里只返回一条。
{ "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==", "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 3, "relation" : "eq" }, "max_score" : 1.0, "hits" : [ { "_index" : "book", "_type" : "_doc", "_id" : "1", "_score" : 1.0, "_source" : { "name" : "Bootstrap开发", "description" : "Bootstrap是一个非常流行的开发框架。此开发框架可以帮助不擅长css页面开发的程序人员轻松的实现一个css,不受浏览器限制的精美界面css效果。", "studymodel" : "201002", "price" : 38.6, "timestamp" : "2019-08-25 19:11:35", "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg", "tags" : [ "bootstrap", "dev" ] } } ] } }
可以看到获取到了第一条的数据,获得的结果里面包含有一个scoll_id,下一次再发送scoll请求的时候,必须带上这个scoll_id,接下来获取第二条数据
GET /_search/scroll { "scroll": "1m", "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==" }
获取成功第二条数据
{ "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==", "took" : 1, "timed_out" : false, "terminated_early" : true, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 3, "relation" : "eq" }, "max_score" : 1.0, "hits" : [ { "_index" : "book", "_type" : "_doc", "_id" : "2", "_score" : 1.0, "_source" : { "name" : "java编程思想", "description" : "java语言是世界第一编程语言,在软件开发领域使用人数最多。", "studymodel" : "201001", "price" : 68.6, "timestamp" : "2019-08-25 19:11:35", "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg", "tags" : [ "java", "dev" ] } } ] } }
每一次都带上上一次的_scroll_id。,接下来获取第三条数据。
GET /_search/scroll { "scroll": "1m", "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==" }
成功获取第三条数据:
{ "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==", "took" : 1, "timed_out" : false, "terminated_early" : true, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 3, "relation" : "eq" }, "max_score" : 1.0, "hits" : [ { "_index" : "book", "_type" : "_doc", "_id" : "3", "_score" : 1.0, "_source" : { "name" : "spring开发基础", "description" : "spring 在java领域非常流行,java程序员都在用。", "studymodel" : "201001", "price" : 88.6, "timestamp" : "2019-08-24 19:11:35", "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg", "tags" : [ "spring", "java" ] } } ] } }