首页 > 其他分享 >Elastic学习之旅 (9) 结构化搜索

Elastic学习之旅 (9) 结构化搜索

时间:2024-04-12 09:03:56浏览次数:26  
标签:结构化 Elastic 之旅 term genre POST Comedy ES

大家好,我是Edison。

上一篇:基于Term和全文的ES查询

结构化数据

结构化搜索(Structured Search)是指对结构化数据的搜索,那么,什么数据是结构化的呢?

ES中日期、布尔类型和数字都是结构化的。

另外,文本也可以是结构化的:

  • 比如彩色笔可以有离散的颜色集合:红、蓝、绿等;

  • 一个博客也可能被标记了一些标签:分布式、搜索、架构等;

  • 电商网站上的商品都有UPCs(通用产品码)或其他的唯一标识,它们都需要遵从严格规定的、结构化的格式。

结构化搜索

结构化搜索(Structured Search)是指对结构化数据的搜索,那么我们接下来就看看如何做结构化搜索。在ES中对结构化数据进行匹配,主要使用term查询。

NOTE:对于文本的全文查询,主要使用match哟。

首先,我们先添加一些测试数据,以便后续场景中的示例。请注意里面这些测试数据的结构,后面两条并没有date字段哟。

DELETE products
POST /products/_bulk
{ "index":{"_id":1}}
{ "productID": "XHDK-A-1293-#fJ3", "price":10, "avaliable":true, "date":"2024-04-01"}
{ "index":{"_id":2}}
{ "productID": "KDKE-B-9947-#kL5", "price":20, "avaliable":true, "date":"2023-04-01"}
{ "index":{"_id":3}}
{ "productID": "J0DL-X-1937-#pV7", "price":30, "avaliable":true }
{ "index":{"_id":4}}
{ "productID": "QQPX-R-3956-#aD8", "price":30, "avaliable":false }

场景1:针对布尔、时间、日期和数字类型的结构化数据

这类数据有精确的格式,可以直接对这些格式进行逻辑操作,比如 比较数字或时间的范围,或判定两个值的大小。

(1)布尔值

// 对布尔值进行查询(有算分)
// ES会返回3条记录
POST /products/_search
{
  "profile": "true",
  "query": {
    "term": {
      "avaliable": true
    }
  }
}

ES返回结果:3条记录,有计算分

从之前的学习中,我们知道,可以使用constant_score转成filtering,进而避免算分,提高性能。

// 对布尔值进行查询(使用constant_score,无算分)
// ES会返回3条记录
POST /products/_search
{
  "profile": "true",
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "avaliable": true
        }
      }
    }
  }
}

ES返回结果:3条记录,没有计算分

(2)数字和日期Range

// 数字Range查询价格>=30 并 <=40的记录
POST /products/_search
{
  "profile": "true",
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "price": {
            "gte": 30,
            "lte": 40
          }
        }
      }
    }
  }
}

// 日期Range查询:查询近一年的记录
// y 年 M 月 w 周 d 天 
// H / h 小时 m 分钟 s 秒
POST /products/_search
{
  "profile": "true",
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "date": {
            "gte": "now-1y"
          }
        }
      }
    }
  }
}

(3)处理空值

// exists 可以过滤不包含某字段的记录
POST /products/_search
{
  "profile": "true",
  "query": {
    "constant_score": {
      "filter": {
        "exists": {
          "field": "date"
        }
      }
    }
  }
}

场景2:针对结构化文本做部分匹配 或 精确匹配

为了演示,我们插入两个测试数据来看看处理多值的情况:

POST /movies/_bulk
{ "index":{"_id":1}}
{ "title": "Father of the Bridge Part II", "year": 1995, "genre": "Comedy" }
{ "index":{"_id":2}}
{ "title": "Dave", "year": 1993, "genre": ["Comedy", "Romance"] }

可以看到,第二条数据的genre字段包含了多个值,是一个集合字段。

然后,我们可以通过term+ keyword来处理多值字段的查询:查找genre属于Comedy(喜剧)的记录。这里需要注意的是,term查询的逻辑关系是包含而不是完全相等,所以它做的是部分匹配

// 查询包含单个值的记录
POST /movies/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "genre.keyword": "Comedy"
        }
      }
    }
  }
}

// 查询包含多个值的记录
POST /movies/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "terms": {
          "genre.keyword": [
            "Comedy",
            "Romance"
          ]
        }
      }
    }
  }
}

这里如果我们想做精确匹配,我们可以增加一个count字段并使用bool查询来解决。

Step1.从业务角度,按需改进ES的数据模型

POST /movies_new/_bulk
{ "index":{"_id":1}}
{ "title": "Father of the Bridge Part II", "year": 1995, "genre": "Comedy", "genre_count":1 }
{ "index":{"_id":2}}
{ "title": "Dave", "year": 1993, "genre": ["Comedy", "Romance"], "genre_count":2 }

这里可以看到,我们给genre字段新增一个匹配的genre_count字段,代表genre字段有几个值。

Step2.使用bool查询进行精确匹配

// 方式一:使用must,有算分
POST /movies_new/_search
{
  "query": {
    "bool": {
      "must": [
        {"term":{"genre.keyword": {"value":"Comedy"}}},
        {"term":{"genre_count": {"value":1}}}
      ]
    }
  }
}
// 方式二:使用filter,无算分
POST /movies_new/_search
{
  "query": {
    "bool": {
      "filter": [
        {"term":{"genre.keyword": {"value":"Comedy"}}},
        {"term":{"genre_count": {"value":1}}}
      ]
    }
  }
}

小结

本篇,我们了解了ElasticSearch中的结构化数据和结构化搜索的概念,并通过几个实例了解了如何对结构化数据进行搜索。在ES中,我们主要使用term对结构化数据进行搜索,而主要使用match对文本进行全文搜索。

参考资料

极客时间,阮一鸣,《ElasticSearch核心技术与实战

 

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

标签:结构化,Elastic,之旅,term,genre,POST,Comedy,ES
From: https://www.cnblogs.com/edisonchou/p/-/edc_elastic_study_notes_chap09

相关文章

  • Elastic Search term, match, match_phrase 和 match_phrase_prefix 查询时的区别
    字段类型分keyword(不分词)和text(分词)字段值为"quickbrownfox",详细的createindex和insertdata语句在后边注意:keyword类型字段不分词,text类型字段keyword类型的字段值就是"quickbrownfox",不分词,必须当成一个整体text类型的字段值是"quickbrownfox",分词,可以当成......
  • 从 Oracle 到 MySQL 数据库的迁移之旅
    目录引言一、前期准备工作1.搭建新的MySQL数据库2.建立相应的数据表2.1数据库兼容性分析2.1.1字段类型兼容性分析2.1.2函数兼容性分析2.1.3是否使用存储过程?存储过程的个数?复杂度?2.1.4是否使用触发器?个数?使用的场景?2.2建表过程中其他需要注意的事项3.为项目配置Oracle和MyS......
  • python 操作 Elasticsearch7.x版本
    目录python操作Elasticsearch7.x版本1.连接Elasticsearch2.索引操作3.文档操作4.查询/搜索文档4.1body和query参数4.2其他查询示例python操作Elasticsearch7.x版本需要先安装这个库pip3installelasticsearch==7.9.1,python版本为3.7及以上这个是elasticsearch库......
  • Elasticsearch之-Django框架集成
    目录Elasticsearch之-Django框架集成一、elasticsearch-dsl库的使用二、与django框架集成Elasticsearch之-Django框架集成需要安装的库:安装:pip3installelasticsearch-dsl一、elasticsearch-dsl库的使用#示例fromdatetimeimportdatetimefromelasticsearch_dslimpo......
  • Elasticsearch 创建自定义分析器(4)
    一.自定义分析器当内置分析器不能满足时,可以创建一个自定义分析器,自定义分析器(analyzer)由:1)0或多个charactcrfilter字符过滤器2) 1个tokenizer分词器,将文本切分为分词  3)0或多个tokenfilter令牌过滤器,是属于分词后再过......
  • 线上扭蛋机小程序:开启虚拟世界的惊喜之旅
    随着移动互联网的飞速发展,各种创新的小程序不断涌现,给人们的生活带来了无限可能。其中,线上扭蛋机小程序以其独特的玩法和惊喜体验,迅速赢得了广大用户的喜爱。线上扭蛋机小程序是一种结合了虚拟世界和实物奖品的创新应用。用户只需在手机上轻轻一点,即可进入这个充满惊喜的虚拟......
  • ElasticSearch
    1.ES是什么https://www.elastic.co/cn/https://www.elastic.co/cn/elastic-stack/1.从事运维,开发,大数据的人员需要学习ElasticSearch数据库2.需要配置日志分析架构,配置ELK技术栈lucene搜索引擎库https://lucene.apache.org/core/ApacheLucene™是一个完全用Java......
  • Go 源码之旅-开篇
    欢迎来到《Go源码之旅》专栏!在这个专栏中,我们将深入探索Go编程语言的内部数据结构的工作原理,一起踏上一段令人兴奋的源码之旅。我们将一步步解析关键的数据结构底层工作原理以及一些常用框架的设计原理及其源码。无论你是初学者还是有经验的开发人员,这个专栏都将为你提......
  • 《解锁数据潜力:开发数据的奇幻之旅》
    在当今数字化的时代,数据成为了最具价值的资产之一。无论是企业还是个人,都意识到了数据的重要性。然而,要充分发挥数据的潜力,就需要进行有效的数据开发。在这篇博客中,我将深入探讨开发数据的重要性、挑战以及如何成功地开展数据开发工作。一、数据开发的重要性洞察市场趋势:......
  • :error=>"Elasticsearch Unreachable: [http://192.168.100.44:9200/][Manticore::Soc
    [2024-04-10T14:02:09,005][WARN][logstash.outputs.elasticsearch]AttemptedtoresurrectconnectiontodeadESinstance,butgotanerror.{:url=>"http://192.168.100.44:9200/",:error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool......