在搜索引擎中,索引建立完之后,只能算是完成了一部分,搜索引擎还涉及到分页,排序,显示等这一些问题,由于在elasticsearch中这些问题都涉及的比较好,实现起来比较简单,这里就一起介绍了。
1、分页
在elasticsearch中有两种分页查询的方法,一种叫做浅分页,一种叫做深分页。
浅分页
下面这个就是浅查询:
POST /_search
{
"size": 2,
"from": 10,
"query": {
"match_all": {}
}
}
其实单词的意思已经很明确了,但还是解释一下,size表示每一页显示2条数据,from表示从第10页开始,也就是说显示的信息是从20-22条数据。这里的排序使用的是默认评分排序。(惭愧,这个评分机制没有去研究)
这个实现的原理是将前22条数据都查询出来,然后根据需要将20-22条数据取出,很显然这种方式在查询页数很多的时候基本上就不能用了,如果查询第50000-50002条数据,需要将前50002数据都取出来,不管从空间还是从时间上都会爆炸的。
不同的博客有不同的说法,有的人说这种查询最多支持10000,也有说50000的,反正就是不能很大。
1. 深分页
POST /_search?scroll=1m
{
"size": 4
}
这个就是深查询,采用scroll查询,这个查询结果会出现一个scroll_id,就是下面这个,scroll=1m表示这个scroll_id维持的时间是1分钟,如果这1分钟没有继续查询,那么这个id就会失效。
"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoEAAAAAAAAC_zFlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAwAhZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAL_QWVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAAC_1FlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAv9hZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAL_cWVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAAC_4FlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAv-RZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAL_oWVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAAC_7FlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAv_BZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAL_0WVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAAC_-FlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAv_xZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAMAAWVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAADABFlVSRk93LUQtUnJTNEVMZHFDNFZPRWc="
接下来,要查询下一页就按照下面这么做就好了。
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id":"DnF1ZXJ5VGhlbkZldGNoEAAAAAAAAC_zFlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAwAhZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAL_QWVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAAC_1FlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAv9hZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAL_cWVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAAC_4FlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAv-RZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAL_oWVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAAC_7FlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAv_BZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAL_0WVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAAC_-FlVSRk93LUQtUnJTNEVMZHFDNFZPRWcAAAAAAAAv_xZVUkZPdy1ELVJyUzRFTGRxQzRWT0VnAAAAAAAAMAAWVVJGT3ctRC1SclM0RUxkcUM0Vk9FZwAAAAAAADABFlVSRk93LUQtUnJTNEVMZHFDNFZPRWc="
}
这种东西就避免了上面的问题,这个id就相当于一个指针的作用,避免了一次性取出过多的数据,但是这种查询方式也有弊端,那就是无法指定页数查询(准确说是我不知道怎么指定页数),只能按顺序一页一页查询。
稍微自己总结一下分页:如果是实现类似百度这种的搜索引擎,可以使用第一种方式,因为用户不可能一下子查看那么多信息,而且第一种方式更加灵活;如果是要将所有数据都全部获取到,则可以使用第二种方式,取出所有数据,便和怎么取没多大关系,之后的操作可以将数据取出之后自己再另做操作。
2. 排序
排序的可以按照下面的方式来:
POST test01/test02/_search
{
"query": {
"match_all": {}
},
"sort": [
{ "good": { "order": "desc" }},
{ "num": { "order": "desc" }}
]
}
3. 选择返回字段
在搜索的时候返回的字段里面可能并不是所有的字段都是需要的,部分加入索引的字段可能只是辅助作用,若这个字段也全都返回,尤其当这个字段的数据量比较大的时候,就很浪费网络资源了
在elasticsearch中通过_source来要求返回的字段是哪些,这里就是只要求返回:”contactperson”,”img”两个字段。
POST /test01/alumniassociation/_search
{
"query": {
"match_all": {}
},
"_source": {
"includes": [
"contactperson",
"img"
]
}
}
这个也是很简单的,一看就懂的那种。
4. 指定创建索引的字段
添加进索引的时候有时候需要指定某些字段是不需要分词或者根本就不用建立索引的(我个人感觉这些字段在很多时候是没有用的,添加进所有浪费资源,或者我还没有用到高级的功能吧),这个时候虽然可以在创建索引mapping是指定analyzer是no还是not-analyzer的,但是这样需要写很多个mapping,显然是不存在的,而且在logstash中也没有办法动态指定需要被analyzer的字段。
在使用logstash同步mysql的时候,配置conf文件的时候需要写入sql语句,类似“select * from test02”,这样的,这样是将所有的字段都添加入索引,如果写成“select id,title,summary from Test02”,则这个时候重新创建索引,只是将指定的字段添加进索引,其他的字段是不会被添加进索引的。