ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch搜索引擎:Elasticsearch、Solr、LuceneELK中的ES:Elasticsearch SolrCloud的搭建、使用 Solr高亮显示 SpringDataSolr使用 Solr的安装与配置 Solr原理、API使用 Lucene原理、API使用 Lucene得分算法客户端库:使用您自己的编程语言与Elasticsearch交互…

大家好,欢迎来到IT知识分享网。

ELK中的ES:Elasticsearch日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)


 

搜索引擎:Elasticsearch、Solr、Lucene

  • ELK中的ES:Elasticsearch
  • SolrCloud 的搭建、使用
  • Solr 高亮显示
  • Spring Data Solr 使用
  • Solr的安装与配置
  • Solr 原理、API 使用
  • Lucene 原理、API使用
  • Lucene 得分算法

 


客户端库:使用您自己的编程语言与 Elasticsearch 交互

官网:https://www.elastic.co/cn/products/elasticsearch

ELK中的ES:Elasticsearch


ElasticsearchELK中的ES:Elasticsearch


将Elasticsearch注册到window的服务上,不用每次启动Elasticsearch

到Elasticsearch的bin目录下,执行以下命令:
服务安装:service install
服务启动:service start
服务停止:service stop
服务卸载:service remove
服务配置管理:service manager

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


ElasticSearch 插件安装 es head

elasticsearch-head插件
	elasticsearch-head是一个elasticsearch的集群管理工具,它是完全由HTML5编写的独立网页程序,
	你可以通过插件把它集成到es。或直接下载源码,在本地打开index.html运行它。
	该工具的Git地址是: https://github.com/Aconex/elasticsearch-head 

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

(推荐使用)方案二:下载解压
	1.插件下载地址https://github.com/mobz/elasticsearch-head
	2.安装方法:
		将下载下的zip文件,解压缩到elasticsearch/plugins/head目录下
		目录路径如下:elasticsearch-2.4.0/plugins/head/

ELK中的ES:Elasticsearch

	3.启动elasticsearch:运行 bin目录下的 elasticsearch.bat 或 服务启动:service start 
	4.访问集群,浏览器地址栏输入 http://localhost:9200/_plugin/head/

ELK中的ES:Elasticsearch


ElasticSearch 基础 数据架构的主要概念 

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


Windows安装CURL命令

ELK中的ES:Elasticsearch

1.使用方式一:cmd命令进入到curl.exe所在的目录下,执行curl --help测试

2.使用方式二:拷贝curl.exe文件到 C:\Windows\System32,然后就可以在DOS窗口中任意位置,使用curl命令了
3.使用方式三:配置环境变量(推荐)
	在系统高级环境变量中,配置 CURL_HOME属性,值为 curl目录的绝对路径
  				path属性中的末尾添加值:;%CURL_HOME%; 

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


curl命令

Elasticsearch 命令的一般格式是:REST VERB HOST:9200/index/doc-type 
	1.REST VERB 指的是RESTFUL风格的 PUT更新/创建、GET获取、DELETE删除
	  使用 curl -X 的动词前缀来明确指定 HTTP 方法:-XPUT、-XGET、-XDELETE。
	2.HOST:9200 指的是 IP地址和端口
	3.index 指的是 索引名称
	4.doc-type 指的是 文档类型

Elasticsearch 创建一个索引

Elasticsearch 创建一个索引名blog,可在您的 shell 中运行以下命令:curl -XPUT "http://localhost:9200/blog/"

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

Elasticsearch 不需要指定文档的类型,比如不需要指定文档的id、title是什么类型,都可以创建索引,因为会自动创建对应的类型。
Lucene 需要指定文档的类型。

 


Elasticsearch 插入一个文档

1.要在 索引名/blog 下创建一个文档类型,然后把文档插入到该文档类型上。
  要将包含 “Deck the Halls” 的文档插入索引中,可运行以下命令(将该命令和本教程的其他 CURL 命令都键入到一行中)
2.命令:curl -XPUT "http://localhost:9200/blog/article/1" -d  "{"""id""":"""1""","""title""":"""Whatiselasticsearch"""}"
  要创建的数据:"{"""id""": """1""", """title""": """Whatiselasticsearch"""}"
  使用 PUT 动词将一个文档添加到 /article文档类型,并为该文档分配 ID 为1。URL 路径显示格式为:http://localhost:9200/index索引/doctype文档类型/ID唯一标识 

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


curl命令查看文档

命令:curl -XGET "http://localhost:9200/blog/article/1"
格式:curl -XGET "http://localhost:9200/index索引/doctype文档类型/ID唯一标识" 
Elasticsearch 使用您之前 PUT 进索引中的 JSON 内容作为响应:

ELK中的ES:Elasticsearch


curl命令更新文档

如果您认识到title字段写错了,并想将它更改为 Whatislucene 怎么办?可运行以下命令来更新文档:
因为此命令使用了相同的唯一 ID为1,所以该文档会被更新。
命令:curl -XPUT "http://localhost:9200/blog/article/1" -d "{"""id""":"""1""","""title""":"""Whatislucene"""}"
      curl -XPOST "http://localhost:9200/blog/article/1" -d "{"""id""":"""1""","""title""":"""Whatislucene"""}"
格式:curl -XPUT http://localhost:9200/index索引/doctype文档类型/ID唯一标识 
      curl -XPOST http://localhost:9200/index索引/doctype文档类型/ID唯一标识 

ELK中的ES:Elasticsearch


curl命令搜索文档

搜索文档:
	基本查询,此查询比您运行来查找 “Get the Halls” 文档的简单 GET 要复杂一些。
	文档 URL 有一个内置的 _search 端点用于此用途。
	在标题中找到所有包含单词 lucene 的数据:curl -XGET "http://localhost:9200/blog/article/_search?q=title:'whatislucene'"(q 参数表示一个查询)
 	格式:curl -XGET "http://localhost:9200/index索引/doctype文档类型/_search?q=title:'查询内容'"

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


检索返回Json对象说明ELK中的ES:Elasticsearch

1.took:该请求花了多少毫秒:
2.timed_out:该请求是否超时
3._shards:需要考虑 Elasticsearch 是一个集群化服务的事实
4.hits:total:它会告诉您获得了多少个结果
    max_score:用于全文搜索
      实际结果包含 fields 属性,因为您将 fields 参数添加到了查询中。
      否则,结果中会包含 source,而且包含完整的匹配文档。_index、_type 和 _id 分别表示索引、文档类型、ID;
5._score 指的是全文搜索命中长度。这 4 个字段始终会在结果中返回。

curl命令删除文档

删除文档:
	命令:curl -XDELETE "http://localhost:9200/blog/article/1"
	格式:curl -XDELETE "http://localhost:9200/index索引/doctype文档类型/ID唯一标识" 

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


删除索引

删除索引:
	命令:curl -XDELETE "http://localhost:9200/blog"
	格式:curl -XDELETE "http://localhost:9200/index索引" 

ELK中的ES:Elasticsearch


使用Java API 操作客户端之创建TransportClient

运行一个 Java 应用程序和 Elasticsearch 时,有两种操作模式可供使用:
	1.Node Client:应用程序实例将请求交给集群处理,然后集群分发给一个 Elasticsearch 节点来处理
	2.Transport Client:将请求交给单独的一个 Elasticsearch 节点 来处理

ELK中的ES:Elasticsearch

1.pom.xml导入依赖
	<dependencies>
  		<dependency>
  			<groupId>org.elasticsearch</groupId>
  			<artifactId>elasticsearch</artifactId>
  			<version>2.4.0</version>
  		</dependency>
  		<dependency>
  			<groupId>junit</groupId>
  			<artifactId>junit</artifactId>
  			<version>4.12</version>
  		</dependency>
  	</dependencies>

2.ElasticSearch 服务默认端口 9300 
  Web 管理平台端口 9200 

3.当直接在ElasticSearch 建立文档对象时,如果索引不存在的,默认会自动创建,映射采用默认方式 。
  这里注意:如果连接到一个 Elasticsearch 集群,构建器可以接受多个地址。
  在本课程中,您只有一个 localhost 节点 连接到端口 9300,而不是像之前在 REST API 的 CURL 中一样连接到 9200。
  Java 客户端将会使用这个特殊端口,使用端口 9200将不起作用。
  使用org.elasticsearch.client.Client连接服务器。所以任何操作都需要用上,我们把它的创建放置到@Before中,操作最后别忘记执行client.close()方法关闭。

4.Transport Client:将请求交给单独的一个 Elasticsearch 节点 来处理
	private Client client;
	//服务器为本机127.0.0.1;ElasticSearch 服务默认端口9300
	client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)) 

ELK中的ES:Elasticsearch

Node Client:应用程序实例将请求交给集群处理,然后集群分发给一个 Elasticsearch 节点来处理
Transport Client:将请求交给单独的一个 Elasticsearch 节点 来处理

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


新建文档,自动创建索引 

 

方式一:拼装json的字符串

ELK中的ES:Elasticsearch

String json = "{" + "\"id\":\"1\"," +
		  "\"title\":\"基于Lucene的搜索服务器\"," +
		  "\"content\":\"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口\"" 
	      + "}"; // \" 表示转义为 "

// 创建索引
IndexResponse indexResponse = this.client.prepareIndex("index索引", "doctype文档类型", "ID唯一标识").setSource(json).execute().actionGet();

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

 

方式二:使用Map集合

Map<String, Object> json = new HashMap<String, Object>();
json.put("id", "2");
json.put("title", "基于Lucene的搜索服务器");
json.put("content", "它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口");

// 创建索引
IndexResponse indexResponse = this.client.prepareIndex("index索引", "doctype文档类型", "ID唯一标识").setSource(json).execute().actionGet();

ELK中的ES:Elasticsearch

 

方式三:使用 ElasticSearch的 帮助类XContentBuilder 来新建文档,创建json对象

XContentBuilder sourceBuilder = XContentFactory.jsonBuilder().startObject()
				.field("id", 3)
				.field("title", "ElasticSearch是一个基于Lucene的搜索服务器")
				.field("content","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口")
				.endObject();

// 创建索引
IndexResponse indexResponse = this.client.prepareIndex("index索引", "doctype文档类型", "ID唯一标识").setSource(json).execute().actionGet();

ELK中的ES:Elasticsearch


搜索文档数据(单个索引)

private Client client;
//服务器为本机127.0.0.1;ElasticSearch 服务默认端口9300
client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)) 

//单个索引
GetResponse response = client.prepareGet("index索引", "doctype文档类型", "ID唯一标识")
                .setOperationThreaded(false) // 线程安全
                .get();

ELK中的ES:Elasticsearch


搜索文档数据(多个索引)

private Client client;
//服务器为本机127.0.0.1;ElasticSearch 服务默认端口9300
client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)) 

//多个索引
MultiGetResponse multiGetResponse = client.prepareMultiGet()
        .add("index索引", "doctype文档类型", "ID唯一标识")
        .add("index索引", "doctype文档类型", "ID唯一标识", "ID唯一标识", "ID唯一标识")
        .add("index索引", "doctype文档类型", "ID唯一标识")
        .get();

ELK中的ES:Elasticsearch


更新文档数据(3种方式):ID存在则更新,ID不存在则保存

更新方式一:
	UpdateRequest updateRequest = new UpdateRequest();
	updateRequest.index("要更新的 index索引");
	updateRequest.type("要更新的 doctype文档类型");  
	updateRequest.id("要更新的 ID唯一标识"); //ID存在则更新,ID不存在则保存
	updateRequest.doc(XContentFactory.jsonBuilder().startObject()
				.field("title", "ElasticSearch是一个基于Lucene的搜索服务器")// 对没有的字段添加, 对已有的字段替换
				.field("content","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口")
				.field("createDate", "2018-10-11").endObject());
	UpdateResponse response = client.update(updateRequest).get();
	client.close();

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

 

更新方式二:
	//使用updateRequest对象 及 documents进行更新
	UpdateResponse response = client.update(new UpdateRequest("index索引", "doctype文档类型", "ID唯一标识") //ID存在则更新,ID不存在则保存
				      .doc(XContentFactory.jsonBuilder().startObject() 
				      .field("title", "什么是Elasticsearch").endObject()))// 对没有的字段添加, 对已有的字段替换
				      .get();
	client.close();

ELK中的ES:Elasticsearch

 

更新方式三:
        // IndexRequest("index索引", "doctype文档类型", "ID唯一标识"):设置查询条件, 根据ID查询。查找不到的话,则添加field所设置的数据
        IndexRequest indexRequest = new IndexRequest("index索引", "doctype文档类型", "ID唯一标识")
            				.source(XContentFactory.jsonBuilder().startObject()
					.field("id", 3)
                				.field("title", "搜索服务器")
					.field("content","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口")
                				.endObject());

       // UpdateRequest("index索引", "doctype文档类型", "ID唯一标识"):设置更新条件, 根据ID查询,查找到的话,则更新下面的field所设置的数据
       UpdateRequest upsert = new UpdateRequest("index索引", "doctype文档类型", "ID唯一标识")
            			.doc(XContentFactory.jsonBuilder().startObject()
                        		.field("user", "李四")
                    		.endObject())
            			.upsert(indexRequest);
        client.update(upsert).get();
        client.close();

ELK中的ES:Elasticsearch

第一次运行程序时,IndexRequest中所设置的ID查找不到,则添加IndexRequest中的field所设置的数据,并且因为UpdateRequest同样也查找不到所设置的ID,
即使这一次添加IndexRequest中的field所设置的数据有该ID,也不会执行UpdateRequest进行数据修改,只有在第二次运行程序时,IndexRequest中所设置的ID查找到了,
然后便会执行UpdateRequest进行数据修改

ELK中的ES:Elasticsearch


删除文档数据

写法一:DeleteResponse response = client.prepareDelete("index索引", "doctype文档类型", "ID唯一标识").get();
写法二:DeleteResponse response = client.prepareDelete("index索引", "doctype文档类型", "ID唯一标识").execute().actionGet();

ELK中的ES:Elasticsearch


IK分词器 

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

在 Elasticsearch/plugins 目录下 创建 analysis-ik 文件夹,用于存储 Ik分词器的相关配置文件

ELK中的ES:Elasticsearch

把 Ik分词器根目录中 target/releases 文件夹中的 部分相关配置文件 拷贝到 Elasticsearch/plugins/analysis-ik 文件夹中

ELK中的ES:Elasticsearch

把 Ik分词器根目录中 target/releases/config 文件夹中的 部分相关配置文件 拷贝到 Elasticsearch/config 文件夹中

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

对 Elasticsearch/config 文件夹中的 elasticsearch.yml文件末尾添加:index.analysis.analyzer-ik.type: "ik"
注意:配置语句中 index.analysis.analyzer-ik.type: 和 "ik" 之间必须有一个空格
作用:该配置语句 表示 名称命名为ik,后续用到分词器的时候,使用ik这个名词。
  

ELK中的ES:Elasticsearch

对 Elasticsearch 配置完 ik 分词器之后,进行重启 Elasticsearch,或者点击 Elasticsearch/bin 目录中的 elasticsearch.bat 启动 Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

http://localhost:9200/_analyze?analyzer=ik&pretty=true&text=中文内容

ELK中的ES:Elasticsearch


IK分词器 配置拓展词典:添加自定义单词ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


创建索引和删除索引

1.在ElasticSearch没有索引情况下 插入文档数据的话,默认创建索引和索引映射,但是无法使用ik分词器。
  所以要想使用IK分词器,需要重新创建索引。
2.创建索引:client.admin().indices().prepareCreate("索引名").get();
3.删除索引:client.admin().indices().prepareDelete("索引名").get();

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


 映射相关操作(创建映射并设置某个字段使用IK分词进行分词)

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

// 通过JSON配置数据的 类型/格式 和 映射关系
// field("store", "yes"):store的值为yes:表示该字段数据存储到索引库中
// field("analyzer", "ik"):analyzer的值为ik:表示该字段数据使用ik分词器进行分词 
// id字段不需要设置分词器,因为id字段不需要进行分词。
XContentBuilder builder = XContentFactory.jsonBuilder()
			.startObject() // 一个startObject必定对应一个endObject,两者组成一对 表示为一组数据
				.startObject("文档类型")
					.startObject("properties") 
						.startObject("字段id").field("type", "integer").field("store", "yes").endObject()
						.startObject("字段title").field("type", "string").field("store", "yes").field("analyzer", "ik").endObject()
						.startObject("字段content").field("type", "string").field("store", "yes").field("analyzer", "ik").endObject()
					.endObject()
				.endObject()
			.endObject();
PutMappingRequest mapping = Requests.putMappingRequest("索引").type("文档类型").source(配置映射关系的JSON); //创建索引的同时设置映射关系对象
client.admin().indices().putMapping(映射关系对象).get();

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


条件查询QueryBuilders 

1.可以使用REST API和简单查询或GET请求来搜索数据。
  更改索引时,无论想执行的操作是更改映射还是文档索引化,都要用REST API向Elasticsearch发送JSON结构的数据。
2.类似地,如果想发送的不是一个简单的查询,仍然把它封装为JSON结构并发送给Elasticsearch。这就是所谓的查询DSL。
  从更宏观的角度看,Elasticsearch支持两种类型的查询:基本查询和复合查询。
	基本查询,如词条查询用于查询实际数据。
	复合查询,如布尔查询,可以合并多个查询。
3.查询数据 主要依赖QueryBuilder对象 ,可以通过QueryBuilders获取各种查询(基于lucene)
	QueryBuilders.boolQuery() 布尔查询,可以用来组合多个查询条件 
	QueryBuilders.fuzzyQuery() 相似度查询 
	QueryBuilders.matchAllQuery() 查询所有数据 
	QueryBuilders.regexpQuery() 正则表达式查询 
	QueryBuilders.termQuery() 词条查询 
	QueryBuilders.wildcardQuery() 模糊查询 


 

1.使用SearchResponse获取,支持各种查询:
	//搜索在elasticSearch中创建的文档对象
	@Test
	public void testSearch() throws Exception 
	{
		// 搜索数据
		// get() == execute().actionGet()
		/* SearchResponse searchResponse = client.prepareSearch("一个或多个index索引")
						      .setTypes("一个或多个doctype文档类型")
						      .setQuery(QueryBuilders.matchAllQuery()).get();
		*/

		/**
		 * 1.第一种用法:ElasticSearch提供QueryBuileders.queryStringQuery("搜索内容")
		 *    	        queryStringQuery查询方法:会对所有每个字段都会进行分词查询,实际进行的是对索引进行查询。
		 *	        如果存储的中文数据使用了IK分词器进行分词并作为索引存储的话,那么此处查询操作便是对IK分词后的索引中文单词进行查询
		 */
 		SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
 						.setQuery(QueryBuilders.queryStringQuery("全面")).get();
 
		/** 
		 * 2.第二种用法:ElasticSearch提供QueryBuileders.wildcardQuery("字段名","搜索内容")
		 *	        比如只查询单个content字段的值中的内容,实际进行的是对索引进行查询。
		 *	        使用QueryBuilders.wildcardQuery进行模糊查询,可加上通配符。比如:* 表示 多个任意字符。? 表示 单个任意字符。
		 *	        如果存储的中文数据使用了IK分词器进行分词并作为索引存储的话,那么此处查询操作便是对IK分词后的索引中文单词进行查询
		 */
 		SearchResponse searchResponse = client.prepareSearch("blog").setTypes("article")
 				.setQuery(QueryBuilders.wildcardQuery("content", "*全?")).get();
 
		/** 3.第三种用法:ElasticSearch提供QueryBuileders.termQuery("字段名","搜索内容")
		 *		比如只查询单个content字段的值中的内容,实际进行的是对索引进行查询。
		 *	         如果存储的中文数据使用了IK分词器进行分词并作为索引存储的话,那么此处查询操作便是对IK分词后的索引中文单词进行查询 
		 */
		SearchResponse searchResponse = client.prepareSearch("blog")
				.setTypes("article")
				.setQuery(QueryBuilders.termQuery("content", "全文")).get();

ELK中的ES:Elasticsearch

		//--------------------------------------------------------
		SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象
		System.out.println("查询结果有:" + hits.getTotalHits() + "条"); //获取出查询结果有多少条记录数
		Iterator<SearchHit> iterator = hits.iterator();//遍历查询结果中每条记录数据
		while (iterator.hasNext()) 
		{
			SearchHit searchHit = iterator.next(); // 获取每个查询对象
			System.out.println(searchHit.getSourceAsString()); // 获取字符串格式打印
			System.out.println("id:" + searchHit.getSource().get("id"));// 获取id字段的值
			System.out.println("title:" + searchHit.getSource().get("title"));;// 获取title字段的值
			System.out.println("content:" + searchHit.getSource().get("content"));;// 获取content字段的值
			for (Iterator<SearchHitField> ite = searchHit.iterator(); ite.hasNext();)
			{
				SearchHitField next = ite.next();
				System.out.println(next.getValues());
			}
		}
		// 关闭连接
		client.close();
	}

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


文档相关操作(使用Jackson创建文档数据)

ELK中的ES:Elasticsearch

2.x 版本 引入jackson:
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-core</artifactId>
		<version>2.8.1</version>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
		<version>2.8.1</version>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-annotations</artifactId>
		<version>2.8.1</version>
	</dependency> 

// 创建连接搜索服务器对象
Client client = TransportClient.builder().build().addTransportAddress( new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
// 描述json 数据 {id:xxx, title:xxx, content:xxx}
 
Article article = new Article();//自定义 JavaBean 类Article 
article.setId(2);
article.setTitle("搜索工作其实很快乐");
article.setContent("我们希望我们的搜索解决方案要快");

ObjectMapper objectMapper = new ObjectMapper();
// 建立文档
client.prepareIndex("index索引", "doctype文档类型", "ID唯一标识" article.getId().toString()).setSource(objectMapper.writeValueAsString(article)).get();
// 关闭连接
client.close();

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch

ELK中的ES:Elasticsearch


修改文档相关操作(使用Jackson修改文档数据)

方式一:使用prepareUpdate、prepareIndex都可以  
	Client client = TransportClient.builder().build().addTransportAddress( new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
	Article article = new Article();//自定义 JavaBean 类Article 
	ObjectMapper objectMapper = new ObjectMapper();
	client.prepareUpdate("index索引", "doctype文档类型", "ID唯一标识").setDoc(objectMapper.writeValueAsString(article)).get();

方式二:直接使用update
	Client client = TransportClient.builder().build().addTransportAddress( new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
	Article article = new Article();//自定义 JavaBean 类Article 
	ObjectMapper objectMapper = new ObjectMapper();
	client.update(new UpdateRequest("index索引", "doctype文档类型", "ID唯一标识").doc(objectMapper.writeValueAsString(article))).get();

ELK中的ES:Elasticsearch


删除文档相关操作

方式一: prepareDelete 
	Client client = TransportClient.builder().build().addTransportAddress( new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
	Article article = new Article();//自定义 JavaBean 类Article 
	client.prepareDelete("index索引", "doctype文档类型", "ID唯一标识").get();

方式二: 直接使用delete 
	Client client = TransportClient.builder().build().addTransportAddress( new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
	Article article = new Article();//自定义 JavaBean 类Article 
	client.delete(new DeleteRequest("index索引", "doctype文档类型", "ID唯一标识").get();

ELK中的ES:Elasticsearch


各种查询

1.查询所有
	// matchAllQuery()匹配所有文件
	// match_all查询是Elasticsearch中最简单的查询之一。它使我们能够匹配索引中的所有文件。
 	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型").setQuery(QueryBuilders.matchAllQuery()).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象

ELK中的ES:Elasticsearch

2.解析字符串查询QueryString
	// 相比其他可用的查询,query_string查询支持全部的Apache Lucene查询语法
	// 针对多字段的query_string查询
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型").setQuery(QueryBuilders.queryStringQuery("搜索内容")).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象
 

3.通配符查询(wildcardQuery)
	// * 表示 匹配多个字符。? 表示 匹配1个字符
	// 注意:避免搜索字符串以 * 开始, 会检索大量内容造成效率缓慢
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
				 .setQuery(QueryBuilders.wildcardQuery("字段名", "搜索内容 通配符 xxx*y?")).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象

 
4.词条查询(termQuery)
	// 词条查询是Elasticsearch中的一个简单查询。它仅匹配在给定字段中含有该词条的文档,而且是确切的、未经分析的词条
	// termQuery("key", obj) 完全匹配
	// termsQuery("key", obj1, obj2..)   一次匹配多个值,只有有一个值是正确的,就可以查询出数据
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
	 			 	.setQuery(QueryBuilders.termQuery("字段名", "搜索内容")).get();
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
				 	.setQuery(QueryBuilders.termsQuery("字段名", "搜索内容1","搜索内容2")).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象

 
5.字段匹配查询
	// matchQuery("key", Obj) 单个匹配, field不支持通配符, 前缀具高级特性
     	// match查询把query参数中的值拿出来,加以分析,然后构建相应的查询。使用match查询时,Elasticsearch将对一个字段选择合适的分析器,所以可以确定,
     	// 传给match查询的词条 将被建立索引时 相同的分析器处理。
     	// multiMatchQuery("text", "field1", "field2"..);  匹配多个字段, field有通配符进行
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
 					.setQuery(QueryBuilders.matchQuery("字段名", "搜索内容")).get();
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
					.setQuery(QueryBuilders.multiMatchQuery( "搜索内容", "字段名1","字段名2")).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象

 

6.只查询ID(标识符查询)
	// 标识符查询是一个简单的查询,仅用提供的标识符来过滤返回的文档。此查询针对内部的 _uid字段运行,所以它不需要启用_id字段
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
					.setQuery(QueryBuilders.idsQuery().ids("ID值")).get();
		SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象
 

7.相似度查询
	// fuzzy查询是模糊查询中的第三种类型,它基于编辑距离算法来匹配文档
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
				.setQuery(QueryBuilders.fuzzyQuery("字段名", "搜索内容")).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象

 

8.范围查询
	// 范围查询使我们能够找到在某一字段值在某个范围里的文档,字段可以是 数值型,也可以是 基于字符串的
	// includeLower(true):包含上界
	// IncludeUpper(true):包含下界
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
				.setQuery(QueryBuilders.rangeQuery("字段名").from("搜索内容1").to("搜索内容2").includeLower(true).includeUpper(true)).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象

 

9.跨度查询
	// 下面代码表示,从首字母开始,查询“字段名=搜索内容”,搜索内容前面的词可以为N个 
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
				.setQuery(QueryBuilders.spanFirstQuery(QueryBuilders.spanTermQuery("字段名", "搜索内容"), 跨度为N个字符的数字)).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象


 

10.组合查询(复杂查询)
	// must(QueryBuilders):AND
	// mustNot(QueryBuilders):NOT
	// should(QueryBuilders):OR 
	定义json:放置到Elasticsearch的插件中
		{ "query" : { "bool" : { "must" : { "term" : { "title" : "elasticsearch" } }, 
					     "should" : { "range" : { "id" : { "from" : 1, "to" : 2 } } } } } }

	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
					.setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("字段名", "搜索内容")).
					must(QueryBuilders.wildcardQuery("字段名", "搜索内容 通配符 xxx*y?"))).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象

 

11.排序查询
	SearchResponse searchResponse = client.prepareSearch("index索引").setTypes("doctype文档类型")
						.setQuery(QueryBuilders.matchAllQuery())
						.addSort("字段名", SortOrder.DESC).get();
	SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象




12.查询文档分页操作 
	// 批量向数据表 插入100条记录 
    	@Test
	public void createDocument100() throws Exception 
	{
		// 创建连接搜索服务器对象
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
		//Mapper映射对象
		ObjectMapper objectMapper = new ObjectMapper();
		for (int i = 1; i <= 100; i++) 
		{
			// JavaBean类 Article对象 描述json 数据
			Article article = new Article();
			article.setId(i);
			article.setTitle(i + "搜索工作其实很快乐");
			article.setContent(i + "我们希望我们的搜索解决方案要快");

			// 建立文档:client.prepareUpdate("index索引", "doctype文档类型", "ID唯一标识").setSource(objectMapper.writeValueAsString(JavaBean类 Article对象)).get()
			client.prepareIndex("blog2", "article", article.getId().toString()).setSource(objectMapper.writeValueAsString(article)).get();
		}
		// 关闭连接
		client.close();
	}
 
	@Test
	// 分页查询,查询所有的方法。searchRequestBuilder 的 setFrom【从0开始】 和 setSize【查询多少条记录】方法实现
	public void testPage() throws Exception 
	{
		// 创建连接搜索服务器对象
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
		// 搜索数据。client.prepareSearch("index索引").setTypes("doctype文档类型") 
		SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2").setTypes("article")
				.setQuery(QueryBuilders.matchAllQuery()); 
		
        		//setFrom():从第几条开始检索,默认是0。
        		//setSize():每页最多显示的记录数。默认每页10条记录
		searchRequestBuilder.setFrom(20).setSize(20); // 此处为 查询第2页数据,每页20条
		// get()方法 === execute().actionGet()方法
		SearchResponse searchResponse = searchRequestBuilder.get();
		printSearchResponse(searchResponse);

		// 关闭连接
		client.close();
	}
13.查询结果高亮显示
	查询结果之所以能高亮显示的原因:查看页面源码分析
	







 
 
	@Test
	// 高亮查询结果 处理 搜索
	public void testHighLight() throws IOException 
	{
		// 创建连接搜索服务器对象
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
		// 创建索引中的映射对象
		ObjectMapper objectMapper = new ObjectMapper();

		// 搜索数据。client.prepareSearch("index索引").setTypes("doctype文档类型").setQuery(QueryBuilders.termQuery("字段名", "列值")) 
		SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2").setTypes("article").setQuery(QueryBuilders.termQuery("content", "搜索"));

		// 配置应用高亮的高亮定义 
		searchRequestBuilder.addHighlightedField("content"); // 对content字段进行高亮
		searchRequestBuilder.setHighlighterPreTags("<em>");  // 前置元素
		searchRequestBuilder.setHighlighterPostTags("</em>");// 后置元素
		// 设置摘要大小
		searchRequestBuilder.setHighlighterFragmentSize(10);
		// 进行查询,返回响应结果
		SearchResponse searchResponse = searchRequestBuilder.get();
		SearchHits hits = searchResponse.getHits(); // 获取命中次数,查询结果有多少对象
		System.out.println("查询结果有:" + hits.getTotalHits() + "条"); // 查询结果数据条数

		Iterator<SearchHit> iterator = hits.iterator();
		while (iterator.hasNext()) 
		{
			SearchHit searchHit = iterator.next(); // 每个查询对象
			// 对结果的高亮片段做拼接处理,替换原有内容。将高亮处理后内容,替换原有内容 (原有内容,可能会出现显示不全 )
			Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
			HighlightField contentField = highlightFields.get("content"); // 对content字段进行高亮,因此先要获取content字段的数据

			// 获取到原有内容并设置每个高亮显示的集中位置:fragment 就是高亮片段
			Text[] fragments = contentField.fragments();
			String content = "";
			for (Text text : fragments) 
			{
	 				content += text;//拼接高亮字段数据
			}
			// 将查询结果转换为自定义的JavaBean对象Article:objectMapper.readValue(查询对象searchHit.getSourceAsString(), JavaBean对象Article.class) 
			Article article = objectMapper.readValue(searchHit.getSourceAsString(), Article.class);

			// 用高亮后内容,替换原有内容。如果值等于空,说明没有高亮的结果		
			if(content != null && !"".equals(content))
			{
				// 用高亮后内容,替换原有内容
				article.setContent(content);				
			}
			System.out.println(article);
		}

		// 关闭连接
		client.close();
	}

ELK中的ES:Elasticsearch


得分(加权)

1.随着应用程序的增长,提高搜索质量的需求也进一步增大。我们把它叫做搜索体验。我们需要知道什么对用户更重要,关注用户如何使用搜索功能。
  这导致不同的结论,例如,有些文档比其他的更重要,或特定查询需强调一个字段而弱化其他字段。这就是可以用到加权的地方。
2.实现流程:在Query和Field中可以设置加权
  例如:创建3条数据,通过加权影响我们的数据结果和得分

3.在Query的查询中定义加权
	1.创建数据,Article中添加一个属性
		public class Article 
		{
			private Integer id;
			private String title;
			private String content;
			private String comment;
		}

	2.重新创建索引和映射,创建文档
	/**创建 索引*/
	@Test
	public void testCreateIndex_boost() throws Exception
	{
		// 创建索引:client.admin().indices().prepareCreate("index索引").get()
		client.admin().indices().prepareCreate("blog1").get();
		//关闭
		client.close();
	}
 
	/**创建 映射*/
	@Test
	public void testCreateIndexMapping_boost() throws Exception
	{
		//构建json的数据格式,创建映射
		XContentBuilder mappingBuilder = XContentFactory.jsonBuilder()
				.startObject()
					.startObject("article") // startObject("doctype文档类型")
						.startObject("properties")
							.startObject("id")//id字段
								.field("type","integer").field("store", "yes")//使用默认的分词器,并把分词后的id索引值进行存储
							.endObject()
							.startObject("title") //使用IK分词器进行分词后的数据作为索引进行存储
								.field("type","string").field("store", "yes").field("analyzer","ik")
							.endObject()
							.startObject("content")
								.field("type","string").field("store", "yes").field("analyzer","ik")
							.endObject()
							.startObject("comment")
								.field("type","string").field("store", "yes").field("analyzer","ik")
							.endObject()
						.endObject()
					.endObject()
				.endObject();
		//Requests.putMappingRequest("index索引").type("doctype文档类型")
		PutMappingRequest request = Requests.putMappingRequest("blog1").type("article").source(mappingBuilder);
		client.admin().indices().putMapping(request).get();
		//关闭
		client.close();
	}
	
	
	/**创建文档*/
	@Test
	public void createDocument_boost() throws Exception
	{
		Article article = new Article();
		//article.setId(1);
 		//article.setTitle("搜索引擎服务器"); // 有搜索
 		//article.setContent("基于restful的数据风格"); // 无搜索
 		//article.setComment("我们学习Elasticsearch搜索引擎服务器");// 有搜索
		
		article.setId(2);
		article.setTitle("什么是Elasticsearch"); // 无搜索
		article.setContent("Elasticsearch搜索引擎服务器"); // 有搜索
		article.setComment("Elasticsearch封装了lucene");// 无搜索
		
		ObjectMapper objectMapper = new ObjectMapper();
		String source = objectMapper.writeValueAsString(article);
		System.out.println("source:"+source);
		//client.prepareUpdate("index索引", "doctype文档类型", "ID唯一标识").setDoc(source).get();
		IndexResponse indexResponse = client.prepareIndex("blog1", "article", article.getId().toString()).setSource(source).get();
		// 获取响应的信息
		System.out.println("索引名称:"+indexResponse.getIndex());
		System.out.println("文档类型:"+indexResponse.getType());
		System.out.println("ID:"+indexResponse.getId());
		System.out.println("版本:"+indexResponse.getVersion());
		System.out.println("是否创建成功:"+indexResponse.isCreated());
		client.close();
	}

	3.测试
	@Test
	public void testQueryString_boost() throws Exception{
		SearchResponse searchResponse = client.prepareSearch("blog1").setTypes("article")
				.setQuery(QueryBuilders.queryStringQuery("搜索").field("content^10").field("title^5").field("comment"))
				.get();
		SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
		// 显示数据
		this.searchValue(hits);
		//关闭
		client.close();
	}
	
	@Test
	public void testBoolQuery_boost() throws Exception{
		SearchResponse searchResponse = client.prepareSearch("blog1").setTypes("article")
				.setQuery(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("title", "搜索").boost(5f))
						.should(QueryBuilders.termQuery("content", "搜索").boost(10f)))
				.get();
		SearchHits hits = searchResponse.getHits();//获取数据的结果集对象,获取命中次数
		// 显示数据
		this.searchValue(hits);
		//关闭
		client.close();
	}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/14358.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信