Elasticsearch高级
Elasticsearch批量操作的查询类型
Bulk批量查询的Java实现
-
package EsTest; import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.transport.client.PreBuiltTransportClient; import java.net.InetAddress; /** * Es简单操作测试 */ public class EsDemo2 { static String index = "test"; static String type = "emp"; public static void main(String[] args) throws Exception{ Settings settings = Settings.builder() .put("cluster.name", "elasticsearch") .put("client.transport.sniff", true) .build(); TransportClient client = new PreBuiltTransportClient(Settings.EMPTY) .addTransportAddress(new TransportAddress(InetAddress.getByName("hadoop110"), 9300)); testBulk(client); } /** * bulk批量查询测试 */ public static void testBulk(TransportClient client){ BulkRequestBuilder bulkRequestBuilder = client.prepareBulk(); //创建请求 IndexRequest indexRequest = new IndexRequest(index, type) .source("{\"name\":\"zs1\",\"age\":25}"); //删除请求 DeleteRequest deleteRequest = new DeleteRequest(index, type, "21",,XContentType.JSON); //将操作整合到buider中 bulkRequestBuilder.add(indexRequest); bulkRequestBuilder.add(deleteRequest); //执行批量操作 BulkResponse bulkItemResponses = bulkRequestBuilder.get(); //查看执行过程中失败的信息 if(bulkItemResponses.hasFailures()){ BulkItemResponse[] items = bulkItemResponses.getItems(); for (BulkItemResponse item: items) { System.out.println(item.getFailureMessage()); } }else { System.out.println("所有bulk指令都执行成功了"); } } }
SearchType的详解
-
query and fetch :当客户机向es集群中的某一个节点发送请求时,这个节点会将请求复制到每一个节点上,然后每一个节点会将所请求的数据返回到查询节点上,然后由查询节点返回到客户机上,这样的优点就是速度快,缺点是不准确,客户想要10条数据,集群返回的是10*n条数据,n是集群的节点数
-
query then fetch:当客户机向集群发送请求时,集群中接收请求的节点也会将查询请求发送到每一个节点之上,但是每个节点只返回查询结果的ID等值给主节点,主节点将受到的数据在进行排序取出所需要的条数,然后根据其ID等到相应节点上取的数据,在将数据返回至客户机。优点是可以准确返回需要条数的请求,且结果相对来说准确,缺点是查询速度慢,是es的默认查询类型
-
DFS D是Distributed,F是frequency的缩写,S是Scatter的缩写,整个单词可能是分布式词频率和文档频率散发的缩写
- dfs简称是初始化散发
- 官方解释是初始化散发其实就是在进行真正的查询之前,先把各个分片的词频率和文档频率收集一下,然后进行词搜索的时候,各分片依据全局的词频率和文档频率进行搜索和排名。
- 通俗一点来说就是统计所有节点的搜索排名的算法,总结到一起可以对整个文档进行精确的算法排名
-
dfs query and fetch:就是加了dfs的query and fetch依然是速度快,但是结果条数多
-
dfs query then fetch:执行过程:首先,从各个节点的搜索排序算法即词频率文档频率等,然后根据整合好的算法在每个节点上取出相应数据的ID等信息,在主节点上再次通过该算法获取准确的数据信息,在通过他们的ID等信息去各个节点获取具体数据返回至客户机上。优点是查询准确率高,但是查询速度慢
-
-
代码写法
-
/** * Es简单操作测试 */ public class EsDemo2 { static String index = "test"; static String type = "emp"; public static void main(String[] args) throws Exception{ Settings settings = Settings.builder() .put("cluster.name", "elasticsearch") .put("client.transport.sniff", true) .build(); TransportClient client = new PreBuiltTransportClient(Settings.EMPTY) .addTransportAddress(new TransportAddress(InetAddress.getByName("hadoop110"), 9300)); //testBulk(client); testSeType(client); } /** * 查询类型的测试 */ public static void testSeType(TransportClient client){ SearchResponse searchResponse = client.prepareSearch(index) //索引库信息 .setQuery(QueryBuilders.matchAllQuery()) //查询规则 所有队列 .setPreference("_shards:1") //指点分片 .setSearchType(SearchType.QUERY_THEN_FETCH) //类型可以自己指定 .get(); SearchHits hits = searchResponse.getHits(); //获取总条数 long totalHits = hits.getTotalHits(); System.out.println("数据的总条数"+totalHits); //打印所有数据内容 SearchHit[] hits1 = hits.getHits(); for (SearchHit hit:hits1) { System.out.println(hit.getSourceAsString()); } } }
-
Elasticsearch分词详解
es索引建立和搜索过程图解
倒排索引介绍
- 表中的各个单词表示文档意思
- 单词ID:记录每个单词的编号
- 单词:单词ID对应的单词
- 文档频率:单词在几个文档中出现过
- 倒排列表:单词出现的文档信息以及单词出现位置信息
- DocID:单词出现的文档的ID
- TF:单词在该文档出现的次数
- POS:单词在文档中出现的位置
分词器Analyzer的介绍
-
分词器就是将数据按以此为单位分开
-
分词器的作用
- 是吧文本中的词按照一定的规则进行切分。
- 分词器所对应的的类是Analyzer是一个抽象类,具体的实现方法要靠他的子类,所以对于不同的语言就可以提供不同的分词器
- 在创建索引以及搜索的时候都会用到分词器,而且这两个过程所用到的分析器必须是同一种分词器
-
分词器的工作流程
- 切分关键词
- 取出停用词
- 对于英文字母,将所有字母转换为小写
-
停用词的介绍
- 有些词在文本中出现的概率很高但是对于文本所携带的信息并没有什么影响
- 英文中的
- a,an,the,of 等
- http://www.ranks.nl/stopwords
- a,an,the,of 等
- 中文的
- 的,了,是,着,以及各种标点符号等等
- http://www.ranks.nl/stopwords/chinese-stopwords
- 的,了,是,着,以及各种标点符号等等
- 文本经过分词的过程以后,这种停用词一般都会被过滤掉,不会被索引
- 如果搜索的词含有停用词一本也会被过滤掉
- 过滤掉停用词可以加快建立索引,减小索引库的文件的大小
-
几个重要的分词器介绍
-
分词器 分词方式 StandardAnalyzer 单词分词器 ChineseAnalyzer 单字分词器 CJKAnalyzer 二分法分词器 IKAnalyzer 词库分词器 -
单字分词以及单词分词的意思是一样的
- “我们是中国人”效果:“我”“们”“是”“中”“国”“人”
-
二分法分词器:按两个字的方式分词
- “我们是中国人”,效果:“我们”、“们是”、“是中”、“中国”、“国人”
-
词库分词器
- 按某种算法造词,然后将词存入到词库,把搜索内容匹配到词库的词然后进行拆分。
-
Elasticsearch分词插件介绍以及使用es-ik
- 官方默认的分词插件对中文的支持不是很好,所以我们需要采用第三方的词库来进行分词,IK就是一个分成不错的分词工具
- 下载地址
- https://github.com/medcl/elasticsearch-analysis-ik/releases
- 将下载好的文件放在ES_HOME/plugins/ik目录下解压
- 解压后就可以使用
- 自己添加词库
- 进入到config文件中
- 创建一个自己存放自己词库的文件夹
- 在文件夹中创建dic文件将自己的词库内容放到所创建的文件中
- 修改IKAnalyzer.cfg.xml文件信息
- 将自己创建的词库加进去
- 重启es就可以使用自己创建的词库了
- 实现热词的自动更新不需要重启es
- 在一台服务器上部署一个Tomcat
- 在Tomcat中的webapp/ROOT 创建hot.doc热词词库
- 通过访问网络端口确定这个热词库可以访问
- 修改IK的配置
- http://192.168.80.100:8080/hot.dic
- 重启es之后就可以在hot.dic文件中动态添加热词,IK会定时从端口中访问该文件然后进行更新热词