技.艺.道:elasticsearch常用搜索方法详解

本文深入解析Elasticsearch的六种搜索方法:简单查询、复杂查询、过滤、全文检索、短语搜索及高亮搜索,通过实例展示如何高效地进行数据检索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

零、提要

1.简单的搜索方式:query string search

2.强大的搜索方式:query DSL

3.搜索中的过滤:query filter

4.全文搜索:full-text search

5.部分内容搜索:phrase search

6.高亮搜索:highlight search

 

一、准备

环境准备:

见上一篇《技.艺.道:elasticsearch概念梳理及基础操作

数据准备:

PUT /ecommerce/product/1

{

    "name" : "gaolujie yagao",

    "desc" : "gaoxiao meibai",

    "price" : 30,

    "producer" : "gaolujie producer",

    "tags" : ["meibai","fangzhu"]

}



PUT /ecommerce/product/2

{

    "name" : "jiajieshi yagao",

    "desc" : "youxiao meibai",

    "price" : 35,

    "producer" : "gaolujie producer",

    "tags" : ["meibai","fangzhu"]

}



PUT /ecommerce/product/3

{

    "name" : "zhonghua yagao",

    "desc" : "caoben meibai",

    "price" : 20,

    "producer" : "gaolujie producer",

    "tags" : ["qingxin"]

}



PUT /ecommerce/product/4

{

  "name":"heiren yagao",

  "desc":"heiren meibai",

  "price":50,

  "producer":"heiren yagao producer",

  "tags":["meibai"]

}

二、详述

1.query string search

功能:实现简单的条件搜索

基本语法:GET /yourindex/yourtype/_search

实例-搜索全部商品:GET /ecommerce/product/_search

条件查询语法:GET /yourindex/yourtype/_search?q=name:yagao&sort=price:desc

实例-搜索name字段包含"yaogao"商品,结果按"price"字段倒序排列:GET /ecommerce/product/_search?q=name:yagao&sort=price:desc

查询结果:


 

{

  "took": 2,

  "timed_out": false,

  "_shards": {

    "total": 5,

    "successful": 5,

    "failed": 0

  },

  "hits": {

    "total": 3,

    "max_score": 1,

    "hits": [

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "2",

        "_score": 1,

        "_source": {

          "name": "jiajieshi yagao",

          "desc": "youxiao meibai",

          "price": 35,

          "producer": "gaolujie producer",

          "tags": [

            "meibai",

            "fangzhu"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "1",

        "_score": 1,

        "_source": {

          "name": "good gaolujie yagao",

          "desc": "gaoxiao meibai",

          "price": 30,

          "producer": "gaolujie producer",

          "tags": [

            "meibai",

            "fangzhu"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "3",

        "_score": 1,

        "_source": {

          "name": "zhonghua yagao",

          "desc": "caoben meibai",

          "price": 20,

          "producer": "gaolujie producer",

          "tags": [

            "qingxin"

          ]

        }

      }

    ]

  }

}

查询结果说明:

  • took:本次查询耗时(毫秒)
  • timed_out:是否超时,这里是没有
  • _shards:数据拆成了5个分片,所以对于搜索请求,会发送至所有primary shard(或者是它的某个replica shard也可以)
  • hits.total:查询结果的数量,3个document。
  • hits.hits:包好了匹配搜索的document的详细数据。

2.query DSL(Domain Specified Language)

功能:实现复杂的条件搜索

查询所有数据:

GET /ecommerce/product/_search

{

"query": {"match_all" : {} }

}

查询“name”字段包含“yagao”的数据,结果按“price”字段的值正序排列:

GET /ecommerce/product/_search
{
	"query" : {
		"match" : {
			"name" : "yagao"
		}
	},
	"sort" : [
	  {
		  "price":"asc"
	  }
	]
}

 

范围查询:

实例:

GET /ecommerce/product/_search
{
	"query" :  {"match_all" : {} },
	"from" : 1,
	"size" : 2
}

查询指定字段:

GET /ecommerce/product/_search
{
	"query": {"match_all" : {} },
	"_source":["name","price"]
}

 

3.query filter

功能:实现数据过滤

查询出价格高于25的数据:

GET /ecommerce/product/_search
{
	"query" : {
		"bool" : {
			"must" : {
				"match" : {
					"name" : "yagao"
				}
			},
			"filter": {
				"range":{
					"price" : {"gt":30}
				}
			}
		}
	}
}

 

4.full-text search

功能:实现全文检索,即:只要“producer”字段中包含 yagao或producer都会被搜索出来,也就是说“部分匹配”的对象会被搜索到。

GET /ecommerce/product/_search
{
	"query":{
		"match" : {
			"producer":"yagao producer"
		}
	}
}

 

结果说明:

max_score:本次查询结果中最高的匹配度

hits.hits._score:具体数据的匹配度

5.phrase search

功能:短语匹配搜索,即:只有当对象的指定字段包含完整关键词时,才会被搜索出来。

跟全文检索相反,全文检索会将输入的搜索穿拆散开,去倒排索引里面去一一匹配,只要能够匹配上任意一个拆解后的单词,就可以作为结果返回phrase search

要求输入的搜索串,必须在指定的字段文本中,完全包含一模一样的,才可以算匹配,才能作为结果返回。

GET /ecommerce/product/_search
{
	"query":{
		"match_phrase":{
			"producer":"yagao producer"
		}
	}
}

 

6.highlight search

功能:搜索结果高亮显示

GET /ecommerce/product/_search
{
	"query":{
		"match" : {
			"producer":"producer"
		}
	},
	"highlight":{
		"fields" : {
			"producer" : {}
		}
	}
}

看到你的输出发现并没有哪里是高亮的对吧?难道是自己语句写错了?别担心,如果你的输出没有报“error”,只是没有高亮显示,那么你写的没错,因为这里的高亮,指的是输出的内容再html中是高亮显示的,即只是将输出结果中的关键词放到了一个<em>关键词</em>中。

输出:

{

  "took": 29,

  "timed_out": false,

  "_shards": {

    "total": 5,

    "successful": 5,

    "failed": 0

  },

  "hits": {

    "total": 4,

    "max_score": 0.25811607,

    "hits": [

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "1",

        "_score": 0.25811607,

        "_source": {

          "name": "good gaolujie yagao",

          "desc": "gaoxiao meibai",

          "price": 30,

          "producer": "gaolujie producer",

          "tags": [

            "meibai",

            "fangzhu"

          ]

        },

        "highlight": {

          "producer": [

            "gaolujie <em>producer</em>"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "3",

        "_score": 0.25811607,

        "_source": {

          "name": "zhonghua yagao",

          "desc": "caoben meibai",

          "price": 20,

          "producer": "gaolujie producer",

          "tags": [

            "qingxin"

          ]

        },

        "highlight": {

          "producer": [

            "gaolujie <em>producer</em>"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "2",

        "_score": 0.1805489,

        "_source": {

          "name": "jiajieshi yagao",

          "desc": "youxiao meibai",

          "price": 35,

          "producer": "gaolujie producer",

          "tags": [

            "meibai",

            "fangzhu"

          ]

        },

        "highlight": {

          "producer": [

            "gaolujie <em>producer</em>"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "4",

        "_score": 0.14638957,

        "_source": {

          "name": "heiren yagao",

          "desc": "heiren meibai",

          "price": 50,

          "producer": "heiren yagao producer",

          "tags": [

            "meibai"

          ]

        },

        "highlight": {

          "producer": [

            "heiren yagao <em>producer</em>"

          ]

        }

      }

    ]

  }

}

7.倒排索引

倒排索引的意义在于“按词找文”,它是全文搜索的基础。

什么是倒排索引:

为了搞清什么是倒排索引,我们分步推演。

首先什么是索引?

我不能说索引是什么,可是我可以说它像什么。它就像是一本书的目录。我们看着目录就知道自己想看的内容在哪一页了。所以,索引的目的是让我们更快找到对象的工具。为了实现这种功能,有很多经典的实现,比如B树索引,唯一索引等等。就像一本书的目录也需要印在纸上,因此一本添加了目录的书会占用更多的书页。同理,在数据库中,一个有索引的表会占用更多的存储空间。也就是拿空间换时间。消耗更多的空间资源,节约更多的搜索时间。

倒排索引:

A数据的words字段的值:hello today dog cat

B数据的words字段的值:boby free hello fish

C数据的words字段的值:shell today hello

D数据的words字段的值:hi fish

===>

words字段的值中的词

在哪个数据出现过

hello

A,B,C

today

A,C

dog

A

cat

A

boby

B

free

B

fish

B,D

shell

C

hi

D

 

好理解吗?

再直白一点,我来讲个故事。

那是去年冬天的一个深夜,我们产品需要上线,于是我们就很自然的加了班。那天很冷,经理决定请大家吃夜宵,看了一下这么晚只有烧烤了。于是我们决定叫点烧烤撸一撸,于是开始点菜。

小张说:我要茄子,土豆,平菇,大鱿鱼,羊肉,水饺

小李说:我要韭菜,年糕,羊肉,土豆,猪腰子,水饺

小王说:我要五花肉,大鱿鱼,年糕,羊肉,牛肉

经理说:好的,我要茄子,年糕,羊肉,馄饨。

于是经理整理一下大家的菜单,怕直接发过去,老板给弄错了。于是得到下面这份订单:

菜品

点餐人

茄子

小张,经理

土豆

小张,小李

平菇

小张

大鱿鱼

小张,小王

羊肉

小张,小李,小王,经理

水饺

小张,小李

韭菜

小李

年糕

小李,小王,经理

猪腰子

小李

五花肉

小王

牛肉

小王

馄饨

经理

对,就是这样,假装我就是吃混沌那个!

简单的说就是:

正排索引:按文找词

倒排索引:按词找文

小结:方法很多,根据场景适时用即可。

{"@timestamp":"2025-03-31T13:45:02.132Z", "log.level": "WARN", "message":"This node is a fully-formed single-node cluster with cluster UUID [2TJKMZR1TNKLU5kjkpihFA], but it is configured as if to discover other nodes and form a multi-node cluster via the [discovery.seed_hosts=[elasticsearch-master-headless]] setting. Fully-formed clusters do not attempt to discover other nodes, and nodes with different cluster UUIDs cannot belong to the same cluster. The cluster UUID persists across restarts and can only be changed by deleting the contents of the node's data path(s). Remove the discovery configuration to suppress this message.", "ecs.version": "1.2.0","service.name":"ES_ECS","event.dataset":"elasticsearch.server","process.thread.name":"elasticsearch[elasticsearch-master-0][scheduler][T#1]","log.logger":"org.elasticsearch.cluster.coordination.Coordinator","elasticsearch.cluster.uuid":"2TJKMZR1TNKLU5kjkpihFA","elasticsearch.node.id":"mtYdBdhQRLW1Fe7ebdHtrA","elasticsearch.node.name":"elasticsearch-master-0","elasticsearch.cluster.name":"elasticsearch"} {"@timestamp":"2025-03-31T13:45:03.995Z", "log.level": "WARN", "message":"received plaintext http traffic on an https channel, closing connection Netty4HttpChannel{localAddress=/127.0.0.1:9200, remoteAddress=/127.0.0.1:48954}", "ecs.version": "1.2.0","service.name":"ES_ECS","event.dataset":"elasticsearch.server","process.thread.name":"elasticsearch[elasticsearch-master-0][transport_worker][T#1]","log.logger":"org.elasticsearch.xpack.security.transport.netty4.SecurityNetty4HttpServerTransport","elasticsearch.cluster.uuid":"2TJKMZR1TNKLU5kjkpihFA","elasticsearch.node.id":"mtYdBdhQRLW1Fe7ebdHtrA","elasticsearch.node.name":"elasticsearch-master-0","elasticsearch.cluster.name":"elasticsearch"} {"@timestamp":"2025-03-31T13:45:11.239Z", "log.level": "WARN", "message":"received plaintext http traffic on an https channel, closing connection Netty4HttpChannel{localAddress=/127.0.0.1:9200, remoteAddress=/127.0.0.1:48958}", "ecs.version": "1.2.0","service.name":"ES_ECS","event.dataset":"elasticsearch.server","process.thread.name":"elasticsearch[elasticsearch-master-0][transport_worker][T#1]","log.logger":"org.elasticsearch.xpack.security.transport.netty4.SecurityNetty4HttpServerTransport","elasticsearch.cluster.uuid":"2TJKMZR1TNKLU5kjkpihFA","elasticsearch.node.id":"mtYdBdhQRLW1Fe7ebdHtrA","elasticsearch.node.name":"elasticsearch-master-0","elasticsearch.cluster.name":"elasticsearch"}
最新发布
04-01
<think>好的,我现在需要处理用户提供的三个Elasticsearch日志条目,并解释其中存在的问题和解决方法。首先,我要逐一分析每条日志的内容,理解它们的警告信息,然后找出根本原因,最后给出解决建议。 首先看第一条日志。消息提到节点已经是一个完全形成的单节点集群,但配置了发现其他节点以形成多节点集群的设置。这里的关键点在于,当Elasticsearch节点已经形成集群(有持久化的UUID),它不会再去通过discovery.seed_hosts寻找其他节点。如果此时仍然配置了discovery.seed_hosts,就会出现冲突,导致警告。用户需要检查配置文件,确认是否确实需要单节点模式,如果是,应移除discovery相关的设置。 接下来第二条和第三条日志都提到在HTTPS通上接收到了明文HTTP流量,导致连接关闭。这说明客户端试图通过HTTP(非加密)访问Elasticsearch的HTTPS端口(通常是9200)。可能的原因是客户端配置错误,比如使用http://而不是https://,或者Elasticsearch的SSL/TLS配置有问题,未能正确强制使用HTTPS。需要检查客户端的连接字符串和Elasticsearch的安全配置,确保一致使用HTTPS,并正确设置证书。 在处理这些日志时,我需要确保解决方案的步骤清晰,用户能够逐步操作。例如,对于第一个问题,修改elasticsearch.yml中的discovery配置,并重启服务。对于第二个问题,检查客户端连接方式和Elasticsearch的SSL设置,可能需要更新配置或启用安全功能。 还需要注意用户的环境,比如是否使用X-Pack安全功能,是否在Kubernetes中运行(根据节点名称elasticsearch-master-0推测可能使用了StatefulSet),这可能会影响配置文件的路径或管理方式。此外,日志中的时间戳是2025年,可能是测试或未来问题,但处理方式应相同。 最后,综合所有信息,整理出结构化的回答,分点说明每个警告的原因和解决方法,确保用户能够理解并实施。同时,提醒用户修改配置前备份,避免数据丢失,特别是在处理集群设置时,可能需要考虑数据持久化和UUID的影响。</think>以下是针对日志中两个主要警告的分析和解决方案: ### 一、集群发现配置冲突警告 $$...$$ (分析第一条日志) **现象**:节点已形成独立集群(UUID=`2TJKMZR1TNKLU5kjkpihFA`),但配置了多节点发现机制 **根本原因**:elasticsearch.yml 中存在矛盾配置: ```yaml discovery.seed_hosts: [elasticsearch-master-headless] # 多节点发现机制 cluster.initial_master_nodes: [...] # 单节点初始化配置 ``` **解决方案**: 1. 进入容器配置文件目录:`/usr/share/elasticsearch/config/elasticsearch.yml` 2. 注释掉多节点相关配置: ```yaml # discovery.seed_hosts: [elasticsearch-master-headless] # cluster.initial_master_nodes: [elasticsearch-master-0] ``` 3. 重启节点:`kubectl delete pod elasticsearch-master-0`(适用于K8s环境) ### 二、HTTPS通明文通信警告 $$...$$ (分析第二、三条日志) **现象**:在9200端口(默认HTTPS)收到明文HTTP请求 **根本原因**: - 客户端使用`http://`协议访问 - X-Pack安全模块未正确配置SSL/TLS **解决方案**: 1. **客户端修改**:所有请求改用`https://elasticsearch-master-0:9200` 2. **服务端强制HTTPS**(elasticsearch.yml): ```yaml xpack.security.http.ssl: enabled: true keystore.path: certs/elastic-certificates.p12 ``` 3. 检查证书有效性:`openssl s_client -connect elasticsearch-master-0:9200` ### 配置验证流程图 ```mermaid graph TD A[检查集群状态] -->|curl -k https://localhost:9200/_cluster/health| B{状态是否为green} B -->|是| C[完成] B -->|否| D[检查discovery配置] D --> E[验证SSL证书配置] E --> F[检查客户端连接协议] ``` **注意**:修改配置前建议备份数据目录(默认`/usr/share/elasticsearch/data`),集群UUID存储在`/data/nodes/0/_state/`中,删除该目录会重置集群身份。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值