Elasticsearch查询

发布时间:2024年01月22日

概要

一、Query DSL

Elasticsearch提供了基于JSON的完整查询DSL(Domain Specific Language 特定域的语言)来定义查询。将查询DSL视为查询的AST(抽象语法树),它由两种子句组成:

  • 叶子查询子句:在特定域中寻找特定的值,如match,term或range查询;
  • 复合子查询:
    复合子查询子句包装其他叶子查询或复合查询,并用于以逻辑方式组合多个查询(例如:bool,dis_max查询),或更改其行为(例如:constant_score查询)。

基本语法:

POST /索引名/_search
{
	"query":{
		"查询类型":{
			"查询条件":"查询条件值"
		}	
	}
}

这里的query代表一个查询对象,里面可以有不同的查询属性

  • 查询类型:

    • match_allmatchtermrange
  • 查询条件
    查询条件会根据查询类型的不同,写法有差异

1.1 查询所有(match_all query)

示例:

POST /activity-index/_search
{
  "query": {
    "match_all": {}
  }
}

关于返回值说明:

  • took:查询花费的时间,单位时毫秒
  • time_out:是否超时
  • _shards:分片信息
  • hits:搜索结果
    • total:搜索总条数
    • max_score:所有结果中文档得分的最高分
    • hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
      • _index:索引库
      • _type:文档类型
      • _id:文档id
      • _score:文档得分
      • _source:文档的源数据

1.2 全文检索(full-text query)

全文搜索能够搜索已分析的文本字段,如商品描述,,活动规则等。使用索引期间应用于字段的同一分析器处理查询字符串。全文搜索的分类很多几个典型的如下:

匹配搜索

全文查询的标准查询,它可以对一个字段进行模糊、短语查询。 match queries 接收text/numerics/dates, 对它们进行分词分析, 再组织成一个boolean查询。可通过operator 指定bool组合操作(or、and 默认是 or )。
数据准备:
索引activity-index中有如下数据:

{
 	"hits" : [
      {
        "_index" : "activity-index",
        "_type" : "_doc",
        "_id" : "fDvaAo0BXPpqwihTV9Sk",
        "_score" : 1.0,
        "_source" : {
          "activityCode" : "111",
          "activityName" : "限时抢购活动001",
          "activityType" : "flash",
          "businessType" : "满减"
        }
      },
      {
        "_index" : "activity-index",
        "_type" : "_doc",
        "_id" : "fjvcAo0BXPpqwihT0tTk",
        "_score" : 1.0,
        "_source" : {
          "activityCode" : "222",
          "activityName" : "限时抢购活动002",
          "activityType" : "flash",
          "businessType" : "满赠"
        }
      },
      {
        "_index" : "activity-index",
        "_type" : "_doc",
        "_id" : "fzvdAo0BXPpqwihTW9Rm",
        "_score" : 1.0,
        "_source" : {
          "activityCode" : "333",
          "activityName" : "商品返金币活动001",
          "activityType" : "goodback",
          "businessType" : "满减"
        }
      },
      {
        "_index" : "activity-index",
        "_type" : "_doc",
        "_id" : "gDvdAo0BXPpqwihTwtSe",
        "_score" : 1.0,
        "_source" : {
          "activityCode" : "444",
          "activityName" : "商品返金币活动002",
          "activityType" : "goodback",
          "businessType" : "满增"
        }
      }
    ]

or关系

match 类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系

POST /activity-index/_search
{
  "query": {
    "match": {
      "activityName": "抢购活动"
    }
  }
}

上面的查询中不仅会查出限时抢购活动,也会查出商品返金币活动;多个词之间是or的关系;

and关系

某些情况下,我们需要更精确查找,我们希望这个关系变成 and ,可以这样做

POST /activity-index/_search
{
  "query": {
    "match": {
      "activityName": {
        "query": "抢购活动",
        "operator": "and"
      }
    }
  }
}

本例中,只要activityName中同时包含了抢购活动的词条才会被检索到。

1.3 短语搜索(match phrase query)

match_phrase 查询用来对一个字段进行短语查询,可以指定 analyzer、slop移动因子。

POST /activity-index/_search
{
  "query": {
    "match_phrase": {
      "activityName": "抢购活动"
    }
  }
}

POST /activity-index/_search
{
  "query": {
    "match_phrase": {
      "activityName": {
        "query": "活动"
      }
    }
  }
}

POST /activity-index/_search
{
  "query": {
    "match_phrase": {
      "activityName": {
        "query": "抢购活动",
        "slop": 2
      }
    }
  }
}

1.4 query string查询

Query String Query提供了无需指定某字段而对文档全文进行匹配查询的一个高级查询,同时可以指定在哪些字段上进行匹配。
基本语法

POST /索引名/_search
{
  "query": {
    "query_string": {
      "default_field": "FIELD",
      "query": "this AND that OR thus"
    }
  }
}

示例

POST /activity-index/_search
{
  "query": {
    "query_string": {
      "query": "1"
    }
  }
}
-- 指定字段
POST /activity-index/_search
{
  "query": {
    "query_string": {
      "query": "1",
      "default_field": "activityName"
    }
  }
}

-- 逻辑查询
POST /activity-index/_search
{
  "query": {
    "query_string": {
      "query": "减 or 限时"
    }
  }
}

-- 多字段
POST /activity-index/_search
{
  "query": {
    "query_string": {
      "fields": ["activityName","activityType"],
      "query": "限时"
    }
  }
}

1.5 多字段匹配搜索(multi match query)

如果需要在多个字段上进行文本搜索,可用multi_matchmulti_matchmatch的基础上支持对多个字段进行文本查询。

POST /activity-index/_search
{
  "query": {
    "multi_match": {
      "fields": ["activityName","activityType"],
      "query": "限时"
    }
  }
}

还可以使用*匹配多个字段

POST /activity-index/_search
{
  "query": {
    "multi_match": {
      "fields": ["activity*"],
      "query": "限时"
    }
  }
}

二、词条级搜索

可以使用term-level queries根据结构化数据中的精确值查找文档。结构化数据的值包括日期范围、IP地址、价格或产品ID。
与全文查询不同,term-level queries不分析搜索词。相反,词条与存储在字段级别中的术语完全匹配。

数据准备:

PUT /book
{
  "settings": {},
  "mappings": {
    "properties": {
      "description":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "price":{
        "type": "float"
      },
      "timestamp":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
    }
  }
}

PUT /book/_doc/1
{
  "name": "lucene",
  "description": "Lucene Core is a Java library providing powerful indexing and search features, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. The PyLucene sub project provides Python bindings for Lucene Core. ",
  "price": 100.45,
  "timestamp": "2020-08-21 19:11:35"
}


PUT /book/_doc/2
{
  "name": "solr",
  "description": "Solr is highly scalable, providing fully fault tolerant distributed indexing, search and analytics. It exposes Lucenes features through easy to use JSON/HTTP interfaces or native clients for Java and other languages.",
  "price": 320.45,
  "timestamp": "2020-07-21 17:11:35"
}


PUT /book/_doc/3
{
  "name": "Hadoop",
  "description": "The Apache Hadoop software library is a framework that allows for the distributed processing of large data sets across clusters of computers using simple programming models.",
  "price": 620.45,
  "timestamp": "2020-08-22 19:18:35"
}
PUT /book/_doc/4
{
  "name": "ElasticSearch",
  "description": "Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力 的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条 款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜 索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢 迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。",
  "price": 999.99,
  "timestamp": "2020-08-15 10:11:35"
}

2.1 词条搜索(term query)

term 查询用于查询指定字段包含某个词项的文档

POST /book/_search
{
  "query": {
    "term": {
      "name": {
        "value": "solr"
      }
    }
  }
}

2.2 词条集合搜索(terms query)

terms查询,用于查询指定字段包含某些词项的文档

POST /book/_search
{
  "query": {
    "terms": {
      "name": [
        "hadoop","solr"
      ]
    }
  }
}

2.3 范围查询(range query)

  • gte:大于等于
  • gt:大于
  • lte:小于等于
  • lt:小于
  • boost:查询权重
POST /book/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 10,
        "lte": 200,
        "boost": 2.0
      }
    }
  }
}

POST book/_search
{
  "query": {
    "range": {
      "timestamp": {
        "gte": "18/08/2020",
        "lte": "2021",
        "format": "dd/MM/yyyy||yyyy"
      }
    }
  }
}

2.4 不为空查询(exists query)

查询指定字段值不为空的文档。相当 SQL 中的 column is not null

POST /book/_search
{
  "query": {
    "exists": {"field": "price"}
  }
}

2.5 词项前缀搜索(prefix query)


POST /book/_search
{
  "query": {
    "prefix": {
      "name": {
        "value": "so"
      }
    }
  }
}

2.6 通配符搜索(wildcard query)


POST /book/_search
{
  "query": {
   "wildcard": {
     "name": {
       "value": "lu*"
     }
   }
  }
}

2.7 正则匹配(regexp query)

regexp允许使用正则表达式进行term查询.注意regexp如果使用不正确,会给服务器带来很严重的性能压力。比如.*开头的查询,将会匹配所有的倒排索引中的关键字,这几乎相当于全表扫描,会很慢。因此如果可以的话,最好在使用正则前,加上匹配的前缀。

POST /book/_search
{
  "query": {
    "regexp": {
      "name": "s*"
    }
  }
}

三、复合搜索(compound query)

3.1 constant_score query

用来包装另一个查询,将查询匹配的文档的评分设为一个常值

POST /book/_search
{
  "query": {
    "term": {
      "description": {
        "value": "solr"
      }
    }
  }
}
POST /book/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "description": "solr"
        }
      },
      "boost": 1.2
    }
  }
}

3.2 布尔搜索(bool query)

bool 查询;bool操作来组合多个查询字句为一个查询。 可用的关键字:

  • must:必须满足
  • filter:必须满足,但执行的是filter上下文,不参与、不影响评分
  • should:或
  • must_not:必须不满足,在filter上下文中执行,不参与、不影响评分
POST /book/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "description": "java"
          }
        }
      ],
      "filter": [
        {
          "term": {
            "name": "solr"
          }
        }
      ],
      "must_not": [
        {
          "range": {
            "price": {
              "gte": 200,
              "lte": 300
            }
          }
        }
      ]
    }
  }
}

四、排序

相关性评分排序

默认情况下,返回的结果是按照 相关性 进行排序的——最相关的文档排在最前

为了按照相关性来排序,需要将相关性表示为一个数值。在 Elasticsearch 中, 相关性得分 由一个浮点数进行表示,并在搜索结果中通过 _score 参数返回, 默认排序是 _score 降序,按照相关性评分升序排序如下。

POST /book/_search
{
  "query": {
    "match": {
      "description": "solr"
    }
  }
}

POST /book/_search
{
  "query": {
    "match": {
      "description": "solr"
    }
  },
  "sort": [
    {
      "_score": {
        "order": "asc"
      }
    }
  ]
}

字段值排序

POST /book/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    }
  ]
}

多级排序
先按照价格排序,再按照相关性排序

POST /book/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      },
      "_score":{
        "order": "desc"
      }
    }
  ]
}

五、分页

POST /book/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    }
  ],
  "from": 2,
  "size": 2
}

六、高亮

POST /book/_search
{
  "query": {
    "match": {
      "name": "elasticsearch"
    }
  },
  "highlight": {
    "pre_tags": "<font color='pink'>",
    "post_tags": "</font>",
    "fields": [{"name":{}},{"description":{}}]
  } 
}

在使用match查询的同时,加上一个highlight属性:

  • pre_tags:前置标签
  • post_tags:后置标签
  • fields:需要高亮的字段
  • name:这里声明name字段需要高亮,后面可以为这个字段设置特有配置,也可以空

七、批量操作

有时候为了减少网络开销,需要将多个命令一次发往服务端进行执行,这时候就需要用到批量操作

批量查询

mget

POST /_mget
{
  "docs": [
    {
      "_index": "book",
      "_id": 1
    },
    {
      "_index": "book",
      "_id": 2
    }
  ]
}

统一索引下批量查询

POST /book/_mget
{
  "docs": [
    {
      "_id": 2
    },
    {
      "_id": 3
    }
  ]
}

POST /book/_search
{
  "query": {
    "ids": {
      "values": [1,4]
    }
  }
}

bulk批量增删改查

bulk操作将文档的增删改查一些列操作,通过一次请求全部做完,减少网络传输次数
语法:

POST /_bulk
{"action":{"metadata":{}}}
{"data"}

如下操作:删除1,新增5,修改2

POST /_bulk
{ "delete": { "_index": "book", "_id": "1" }}
{ "create": { "_index": "book", "_id": "5" }}
{ "name": "test14","price":100.99 }
{ "update": { "_index": "book", "_id": "2"} }
{ "doc" : {"name" : "test"} }

功能

  • delete:删除一个文档,只要1个json串就可以了 删除的批量操作不需要请求体
  • create:相当于强制创建 PUT /index/type/id/_create
  • index:普通的put操作,可以是创建文档,也可以是全量替换文档
  • update:执行的是局部更新partial update操作

格式:每个json不能换行。相邻json必须换行。
隔离:每个操作互不影响。操作失败的行会返回其失败信息

实际用法
bulk请求一次不要太大,否则一下积压到内存中,性能会下降。所以,一次请求几千个操作、大小在几M正好。
bulk会将要处理的数据载入内存中,所以数据量是有限的,最佳的数据量不确定,它取决于你的硬件、文档大小以及复杂性,也跟索引以及搜索的负载有关。
一般建议是1000-5000个文档,大小建议是5-15MB,默认不能超过100M,可以在es的配置文件(ES的config下的elasticsearch.yml)中配置。
http.max_content_length: 10mb

文章来源:https://blog.csdn.net/weixin_42612223/article/details/135488636
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。