Elasticsearch:使用 intervals query - 根据匹配项的顺序和接近度返回文档

news2024/9/28 15:30:58

Intervals query 根据匹配项的顺序和接近度返回文档。Intervals 查询使用匹配规则,由一小组定义构成。 然后将这些规则应用于指定字段中的术语。

这些定义产生跨越文本正文中的术语的最小间隔序列。 这些间隔可以通过父源进一步组合和过滤。

上述描述有点费解。我们先用一个简单的例子来进行说明。

示例请求

以下 intervals 搜索返回在 my_text 字段中包含 my favorite food 的文档,并且没有任何间隙,紧接着是在 my_text 字段中包含 hot water 或者 cold porridge。

此搜索将匹配 my_text 字段值为 my favorite food is cold porridge,但是 它不匹配 my_text 的值是 it's cold my favorite food is porridge。

我们首先来写入如下的两个文档:

PUT intervals_index/_doc/1
{
  "my_text": "my favorite food is cold porridge"
}

PUT intervals_index/_doc/2
{
  "my_text": "it's cold my favorite food is porridge"
}

PUT intervals_index/_doc/3
{
  "my_text": "he says my favorite food is banana, and he likes to drink hot water"
}

PUT intervals_index/_doc/4
{
  "my_text": "my favorite fluid food is cold porridge"
}

PUT intervals_index/_doc/5
{
  "my_text": "my favorite food is banana"
}

PUT intervals_index/_doc/6
{
  "my_text": "my most favorite fluid food is cold porridge"
}

我做如下的查询:

GET intervals_index/_search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "all_of" : {
          "ordered" : true,
          "intervals" : [
            {
              "match" : {
                "query" : "my favorite food",
                "max_gaps" : 0,
                "ordered" : true
              }
            },
            {
              "any_of" : {
                "intervals" : [
                  { "match" : { "query" : "hot water" } },
                  { "match" : { "query" : "cold porridge" } }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

上面命令返回的结果为:

{
  "took": 473,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.3333333,
    "hits": [
      {
        "_index": "intervals_index",
        "_id": "1",
        "_score": 0.3333333,
        "_source": {
          "my_text": "my favorite food is cold porridge"
        }
      },
      {
        "_index": "intervals_index",
        "_id": "3",
        "_score": 0.111111104,
        "_source": {
          "my_text": "he says my favorite food is banana, and he likes to drink hot water"
        }
      }
    ]
  }
}

从返回的结果中,我们可以看出来文档 1 及 3 匹配。其原因很简单。两个文档中都含有 my favorite food,并且在它的后面还接着 cold porridge 或者 hot water 尽管它们还是离它们有一定的距离。文档 4 没有匹配是因为在 my favorite food 中间多了一个 fluid 单词。我们在查询的要求中说明 max_gaps 为 0。如果我做如下的查询:

GET intervals_index/_search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "all_of" : {
          "ordered" : true,
          "intervals" : [
            {
              "match" : {
                "query" : "my favorite food",
                "max_gaps" : 1,
                "ordered" : true
              }
            },
            {
              "any_of" : {
                "intervals" : [
                  { "match" : { "query" : "hot water" } },
                  { "match" : { "query" : "cold porridge" } }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

在上面,我们设置 max_gaps 为 1,那么匹配的结果变为:

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 3,
      "relation": "eq"
    },
    "max_score": 0.3333333,
    "hits": [
      {
        "_index": "intervals_index",
        "_id": "1",
        "_score": 0.3333333,
        "_source": {
          "my_text": "my favorite food is cold porridge"
        }
      },
      {
        "_index": "intervals_index",
        "_id": "4",
        "_score": 0.25,
        "_source": {
          "my_text": "my favorite fluid food is cold porridge"
        }
      },
      {
        "_index": "intervals_index",
        "_id": "3",
        "_score": 0.111111104,
        "_source": {
          "my_text": "he says my favorite food is banana, and he likes to drink hot water"
        }
      }
    ]
  }
}

很显然这次文档 4,也即 my favorite fluid food is cold porridge 也被搜索到。而文档 6,也即 my most favorite fluid food is cold porridge 没有被搜索到。

Intervals query 解决的问题

我们在一些论坛上经常看到一个非常常见的问题:“我如何创建一个匹配的查询,同时保留搜索词的顺序?”

他们中的许多人首先尝试使用  match_phrase,但有时他们也想使用 fuzzy 逻辑,而这不适用于 match_phrase。

在很多解决方案中我们可以发现使用 Span Queries 可以解决问题,但是很多问题可以通过使用 Intervals Query 来完美解决。

Intervals Query是一种基于顺序和匹配规则的查询类型。 这些规则是你要应用的查询条件。

今天我们可以使用以下规则:

  • match:match 规则匹配分析的文本。
  • prefix:prefix 规则匹配以指定字符集开头的术语
  • wildcard:wildcard(通配符)规则使用通配符模式匹配术语。
  • fuzzy:fuzzy 规则匹配与给定术语相似的术语,在 Fuzziness 定义的编辑距离内。
  • all_of:all_of 规则返回跨越其他规则组合的匹配项。
  • any_of:any_of 规则返回由其任何子规则生成的 intervals。

示例

我们先准备数据。我们想创建如下的一个 movies 的索引:

PUT movies
{
  "settings": {
    "analysis": {
      "analyzer": {
        "en_analyzer": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "stop"
          ]
        },
        "shingle_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "shingle_filter"
          ]
        }
      },
      "filter": {
        "shingle_filter": {
          "type": "shingle",
          "min_shingle_size": 2,
          "max_shingle_size": 3
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "en_analyzer",
        "fields": {
          "suggest": {
            "type": "text",
            "analyzer": "shingle_analyzer"
          }
        }
      },
      "actors": {
        "type": "text",
        "analyzer": "en_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "description": {
        "type": "text",
        "analyzer": "en_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "director": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "genre": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "metascore": {
        "type": "long"
      },
      "rating": {
        "type": "float"
      },
      "revenue": {
        "type": "float"
      },
      "runtime": {
        "type": "long"
      },
      "votes": {
        "type": "long"
      },
      "year": {
        "type": "long"
      },
      "title_suggest": {
        "type": "completion",
        "analyzer": "simple",
        "preserve_separators": true,
        "preserve_position_increments": true,
        "max_input_length": 50
      }
    }
  }
}

我们接下来使用 _bulk 命令来写入一些文档到这个索引中去。我们使用这个链接中的内容。我们使用如下的方法:

POST movies/_bulk
{"index": {}}
{"title": "Guardians of the Galaxy", "genre": "Action,Adventure,Sci-Fi", "director": "James Gunn", "actors": "Chris Pratt, Vin Diesel, Bradley Cooper, Zoe Saldana", "description": "A group of intergalactic criminals are forced to work together to stop a fanatical warrior from taking control of the universe.", "year": 2014, "runtime": 121, "rating": 8.1, "votes": 757074, "revenue": 333.13, "metascore": 76}
{"index": {}}
{"title": "Prometheus", "genre": "Adventure,Mystery,Sci-Fi", "director": "Ridley Scott", "actors": "Noomi Rapace, Logan Marshall-Green, Michael Fassbender, Charlize Theron", "description": "Following clues to the origin of mankind, a team finds a structure on a distant moon, but they soon realize they are not alone.", "year": 2012, "runtime": 124, "rating": 7, "votes": 485820, "revenue": 126.46, "metascore": 65}
 
....

在上面,为了说明的方便,我省去了其它的文档。你需要把整个 movies.txt 的文件拷贝过来,并全部写入到 Elasticsearch 中。它共有1000 个文档。

我们想要检索符号如下条件的文件:

我们想要检索包含单词 mortal hero 的准确顺序 (ordered=true) 的文档,并且我们不打算在单词之间添加间隙 (max_gaps),因此内容必须与 mortal hero 完全匹配。

GET movies/_search
{
  "query": {
    "intervals": {
      "description": {
        "match": {
          "query": "hero mortal",
          "max_gaps": 0,
          "ordered": true
        }
      }
    }
  }
}

此搜索的结果将为空,因为未找到符合这些条件的文档。

让我们将 ordered 更改为 false,因为我们不关心顺序。

GET movies/_search
{
  "query": {
    "intervals": {
      "description": {
        "match": {
          "query": "hero mortal",
          "max_gaps": 0,
          "ordered": false
        }
      }
    }
  }
}

上面搜索的结果为:

现在我们可以看到文件已经找到了。 请注意,在文档中的 description 是 “Mortal hero”。因为我们想测试相同顺序的术语,所以我们搜索 “mortal hero”:

GET movies/_search
{
  "query": {
    "intervals": {
      "description": {
        "match": {
          "query": "mortal hero",
          "max_gaps": 0,
          "ordered": true
        }
      }
    }
  }
}

这次,我们可以看到和上面命令运行一样的结果。有一个文档被匹配。

让我们在下一个示例中使用 any_of 规则。 我们想要带有 “mortal hero” 或 “mortal man” 的​​文件。

GET movies/_search
{
  "query": {
    "intervals": {
      "description": {
        "any_of": {
          "intervals": [
            {
              "match": {
                "query": "mortal hero",
                "max_gaps": 0,
                "ordered": true
              }
            },
            {
              "match": {
                "query": "mortal man",
                "max_gaps": 0,
                "ordered": true
              }
            }
          ]
        }
      }
    }
  }
}

上面命令返回结果:

请注意,我们成功了。 返回了两个匹配的文档。

我们也可以组合规则。 在示例中,让我们搜索 “the hunger games”,结果中至少有一个是 “part 1” 或 “part 2”。 请注意,这里我们使用角色 match 和 any_of。 

GET movies/_search
{
  "query": {
    "intervals" : {
      "title" : {
        "all_of" : {
          "intervals" : [
            {
              "match" : {
                "query" : "the hunger games",
                "ordered" : true
              }
            },
            {
              "any_of" : {
                "intervals" : [
                  { "match" : { "query" : "part 1" } },
                  { "match" : { "query" : "part 2" } }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

上面命令返回结果:

如上所示结果中只有两部电影。

间隔查询是一种按照搜索词顺序搜索文档的方法。阅读官方文档并了解如何通过它解决问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/349429.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机网络】HTTPS协议原理

文章目录一、认识HTTPS协议二、为什么要发明HTTPS三、HTTP与HTTPS的区别四、常见的加密方式1. 对称加密2. 非对称加密3. 数据摘要4. 数字签名五、HTTPS的原理探究方案1:只使用对称加密方案2:只使用非对称加密方案3:双方都使用非对称加密方案4…

2.15学习总结

上次被学长的问题给问住了,突然发现自己动规有点糊涂,然后就去屁颠屁颠的复习,找几个之前做过的题,突然发现,竟然还是写了好久才写出来,怎么说呢,信心被强烈打击到,然后自己找了一个…

MyBatis 之二(增、删、改操作)

文章目录1. 修改操作1.1 在 mapper&#xff08;interface&#xff09;里面添加修改方法的声明1.2 在 XMl 中添加 <update> 标签和修改的 sql 代码1.3 在 UserMapper 中右键 Generate 点击 Test 生成 update 测试类2. 删除操作2.1 在 mapper &#xff08;interface&#x…

重生之我是赏金猎人-SRC漏洞挖掘(六)-记一次有趣的客户端RCE+服务端XXE挖掘

0x01 起因 朋友给某甲方做渗透测试&#xff0c;奈何甲方是某知名保险&#xff0c;系统太耐艹&#xff0c;半天不出货 兄弟喊我来一块来看&#xff0c;于是有了本文 0x02 客户端RCE一处 朋友把靶标发给我看了下&#xff0c;除了两个下载链接啥也没有 链接下载下来的东西如图…

回溯算法理论基础

目录什么是回溯法回溯法的效率回溯法解决的问题如何理解回溯法回溯法模板什么是回溯法 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。 回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 所以以下讲解中&#xff0c;回溯函数也就是递归函数&#xff0c;指…

SpringCloud: sentinel降级配置、热点参数、系统规则 配置到nacos

一、application.yml spring.cloud.sentinel cloud:nacos:discovery:# 服务注册地址server-addr: xxx.xxx.xxx.xxx:8848sentinel:eager: truetransport:# 控制台地址dashboard: localhost:9999# nacos配置持久化datasource:ds2:nacos:server-addr: xxx.xxx.xxx.xxx:8848dataId…

YOLO 格式数据集制作

目录 1. YOLO简介 2.分割数据集准备 3.代码展示 整理不易&#xff0c;欢迎一键三连&#xff01;&#xff01;&#xff01; 1. YOLO简介 YOLO&#xff08;You Only Look Once&#xff09;是一种流行的目标检测和图像分割模型&#xff0c;由华盛顿大学的 Joseph Redmon 和 Al…

B端产品设计表单的主要分类和相关控件认识

在 Ant、TDesign、Arco 等开源系统中&#xff0c;表单的控件罗列、解释都已经非常全面了&#xff0c;即使是新手完整的看一遍&#xff08;这可不能偷懒&#xff5e;&#xff09;&#xff0c; 也能对表单相关控件有个大致的认识了。 之所以还要更新今天这篇内容&#xff0c;就是…

「5」线性代数(期末复习)

&#x1f680;&#x1f680;&#x1f680;大家觉不错的话&#xff0c;就恳求大家点点关注&#xff0c;点点小爱心&#xff0c;指点指点&#x1f680;&#x1f680;&#x1f680; 目录 第四章 向量组的线性相关性 &5&#xff09;向量空间 第五章 相似矩阵及二次型 &a…

HIVE 安装

目录 启动hadoop 把hive压缩包拷贝到虚拟机里面 解压 改名 配置环境变量 新建一个hive-site.xml文件&#xff0c;并编辑 配置文件 添加jar包 初始化mysql 启动hive 创建数据库 使用数据库 创建表 添加数据 查看数据 删除表 安装虚拟机 安装JDK 安装Hadoop …

亿级高并发电商项目-- 实战篇 --万达商城项目 九(广告服务、安装Redis优化用户缓存、广告服务实现类等开发)

专栏&#xff1a;高并发---分布式项目 亿级高并发电商项目-- 实战篇 --万达商城项目搭建 一 &#xff08;商家端与用户端功能介绍、项目技术架构、数据库表结构等设计&#xff09; 亿级高并发电商项目-- 实战篇 --万达商城项目搭建 一 &#xff08;商家端与用户端功能介绍、项…

多功能手机-课后程序(JAVA基础案例教程-黑马程序员编著-第三章-课后作业)

【案例3-3】多功能手机 记得 关注&#xff0c;收藏&#xff0c;评论哦&#xff0c;作者将持续更新。。。。 【案例介绍】 案例描述 随着科技的发展&#xff0c;手机的使用已经普及到每个家庭甚至个人&#xff0c;手机的属性越来越强大&#xff0c;功能也越来越多&#xff0c;因…

测试开发之Django实战示例 第十一章 渲染和缓存课程内容

第十一章 渲染和缓存课程内容在上一章中&#xff0c;使用了模型继承和通用关系建立弹性的课程、章节和内容的关联数据模型&#xff0c;并且建立了一个CMS系统&#xff0c;在其中使用了CBV&#xff0c;表单集和AJAX管理课程内容。在这一章将要做的事情是&#xff1a;创建公开对外…

数据建模工具:GeneXproTools 5.0 Crack

什么是 GeneXproTools&#xff1f; Microsoft 屡获殊荣的 GeneXproTools 是一种极其灵活的建模工具&#xff0c;专为 回归、逻辑回归、分类、时间序列预测和逻辑综合而设计。GeneXproTools 非常易于使用&#xff0c;实际上就像导入数据一样简单&#xff0c;然后单击一个按钮&a…

【nodejs-05】黑马nodejs学习笔记05-数据库基本操作01

文章目录3.MySQL的基本使用3.1 使用 MySQL Workbench 管理数据库3.2 使用 SQL 管理数据库3.3 SQL 的 SELECT 语句3.4 SQL 的 INSERT INTO 语句3.5 SQL 的 UPDATE 语句3.6 SQL 的 DELETE 语句3.7 SQL 的 WHERE 子句3.8 SQL 的 AND 和 OR 运算符3.9 SQL 的 ORDER BY 子句3.10 SQL…

重生之我是赏金猎人-SRC漏洞挖掘(九)-从本无法触发的xss到梦幻联动挖掘多个致命接口下的XSS触发点

0x00 前言 https://github.com/J0o1ey/BountyHunterInChina 欢迎亲们点个star 作者&#xff1a;画风m78sec 在不久前参加了一次众测项目&#xff0c;需对某厂商的系统进行漏洞挖掘 在测试一套系统时&#xff0c;发现了很有意思的接口&#xff0c;可以操作另外两个站的输出…

Java高手速成 | Java web 实训之投票系统

01、投票系统的案例需求 在本篇中,我们将制作一个投票系统,让学生给自己喜爱的老师投票。该系统由1个界面组成,系统运行,出现投票界面,如图所示: ▍显示效果 在这个界面中,标题为:“欢迎给教师投票”;在界面上有一个表格,显示了各位教师的编号、姓名、得票数;其中…

使用JDBC实现QQ登录

在实际开发中&#xff0c;用户信息是存放在数据库中的&#xff0c;登录时的账号和密码信息也需要去数据库中查询&#xff0c;本节将使用JDBC技术来完善QQ登录案例。1.创建数据表&#xff0c;并添加用户数据在jdbc数据库中创建数据表tb_qquser,并在表中插入3条数据&#xff0c;其…

力扣sql简单篇练习(十七)

力扣sql简单篇练习(十七) 1 销售分析| 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 可以考虑使用all函数 SELECT seller_id FROM Sales GROUP BY seller_id HAVING sum(price)>all(SELECT sum(price)FROM SalesGROUP BY seller_id )1.3 运行…

ChatGpt : 基于OpenAI + Flask快速搭建个人领域内的Q/A问答接口—嵌入网站内知识

文章目录学习前言OpenAI简介Q/A问答接口实现流程1、网络爬虫2、构建嵌入索引3、使用嵌入构建Q/A问答系统4、基于flask框架进行接口封装5、接口测试使用学习前言 最近ChatGpt太火热了&#xff0c;赶紧来了解一波相关情况… 目前来说ChatGpt只有2021年之前的知识&#xff0c;如果…