Elasticsearch:使用查询规则(query rules)进行搜索
在之前的文章 “Elasticsearch 8.10 中引入查询规则 - query rules”,我们详述了如何使用 query rules 来进行搜索。这个交互式笔记本将向你介绍如何使用官方 Elasticsearch Python 客户端来使用查询规则。 你将使用 query rules API 将查询规则存储在 Elasticsearch 中,并使用 rule_query 查询它们。
安装
安装 Elasticsearch 及 Kibana
如果你还没有安装好自己的 Elasticsearch 及 Kibana,那么请参考一下的文章来进行安装:
-
如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch
-
Kibana:如何在 Linux,MacOS 及 Windows 上安装 Elastic 栈中的 Kibana
在安装的时候,请选择 Elastic Stack 8.x 进行安装。在安装的时候,我们可以看到如下的安装信息:
环境变量
在启动 Jupyter 之前,我们设置如下的环境变量:
export ES_USER="elastic"
export ES_PASSWORD="xnLj56lTrH98Lf_6n76y"
export ES_ENDPOINT="localhost"
请在上面修改相应的变量的值。这个需要在启动 jupyter 之前运行。
拷贝 Elasticsearch 证书
我们把 Elasticsearch 的证书拷贝到当前的目录下:
$ pwd
/Users/liuxg/python/elser
$ cp ~/elastic/elasticsearch-8.12.0/config/certs/http_ca.crt .
$ ls http_ca.crt
http_ca.crt
安装 Python 依赖包
python3 -m pip install -qU elasticsearch load_dotenv
准备数据
我们在项目当前的目录下创建如下的数据文件:
query-rules-data.json
[{"id": "us1","content": {"name": "PureJuice Pro","description": "PureJuice Pro: Experience the pinnacle of wireless charging. Blending rapid charging tech with sleek design, it ensures your devices are powered swiftly and safely. The future of charging is here.","price": 15.00,"currency": "USD","plug_type": "B","voltage": "120v"}},{"id": "uk1","content": {"name": "PureJuice Pro - UK Compatible","description": "PureJuice Pro: Redefining wireless charging. Seamlessly merging swift charging capabilities with a refined aesthetic, it guarantees your devices receive rapid and secure power. Welcome to the next generation of charging.","price": 20.00,"currency": "GBP","plug_type": "G","voltage": "230V"}},{"id": "eu1","content": {"name": "PureJuice Pro - Wireless Charger suitable for European plugs","description": "PureJuice Pro: Elevating wireless charging. Combining unparalleled charging speeds with elegant design, it promises both rapid and dependable energy for your devices. Embrace the future of wireless charging.","price": 18.00,"currency": "EUR","plug_type": "C","voltage": "230V"}},{"id": "preview1","content": {"name": "PureJuice Pro - Pre-order next version","description": "Newest version of the PureJuice Pro wireless charger, coming soon! The newest model of the PureJuice Pro boasts a 2x faster charge than the current model, and a sturdier cable with an eighteen month full warranty. We also have a battery backup to charge on-the-go, up to two full charges. Pre-order yours today!","price": 36.00,"currency": "USD","plug_type": ["B", "C", "G"],"voltage": ["230V", "120V"]}}
]
创建应用并展示
我们在当前的目录下打入如下的命令来创建 notebook:
$ pwd
/Users/liuxg/python/elser
$ jupyter notebook
导入包及连接到 Elasticsearch
from elasticsearch import Elasticsearch
from dotenv import load_dotenv
import osload_dotenv()openai_api_key=os.getenv('OPENAI_API_KEY')
elastic_user=os.getenv('ES_USER')
elastic_password=os.getenv('ES_PASSWORD')
elastic_endpoint=os.getenv("ES_ENDPOINT")url = f"https://{elastic_user}:{elastic_password}@{elastic_endpoint}:9200"
client = Elasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)print(client.info())
索引一些测试数据
我们的客户端已设置并连接到我们的 Elastic 部署。 现在我们需要一些数据来测试 Elasticsearch 查询的基础知识。 我们将使用具有以下字段的小型产品索引:
name
description
price
currency
plug_type
voltage
运行以下命令上传一些示例数据:
import json# Load data into a JSON object
with open('query-rules-data.json') as f:docs = json.load(f)operations = []
for doc in docs:operations.append({"index": {"_index": "products_index", "_id": doc["id"]}})operations.append(doc["content"])
client.bulk(index="products_index", operations=operations, refresh=True)
我们可以在 Kibana 中进行查看:
搜索测试数据
首先,让我们搜索数据寻找 “reliable wireless charger.”。
在搜索数据之前,我们将定义一些方便的函数,将来自 Elasticsearch 的原始 JSON 响应输出为更易于理解的格式。
def pretty_response(response):if len(response['hits']['hits']) == 0:print('Your search returned no results.')else:for hit in response['hits']['hits']:id = hit['_id']score = hit['_score']name = hit['_source']['name']description = hit['_source']['description']price = hit["_source"]["price"]currency = hit["_source"]["currency"]plug_type = hit["_source"]["plug_type"]voltage = hit["_source"]["voltage"]pretty_output = (f"\nID: {id}\nName: {name}\nDescription: {description}\nPrice: {price}\nCurrency: {currency}\nPlug type: {plug_type}\nVoltage: {voltage}\nScore: {score}")print(pretty_output)def pretty_ruleset(response):print("Ruleset ID: " + response['ruleset_id'])for rule in response['rules']:rule_id = rule['rule_id']type = rule['type']print(f"\nRule ID: {rule_id}\n\tType: {type}\n\tCriteria:")criteria = rule['criteria']for rule_criteria in criteria:criteria_type = rule_criteria['type']metadata = rule_criteria['metadata']values = rule_criteria['values']print(f"\t\t{metadata} {criteria_type} {values}")ids = rule['actions']['ids']print(f"\tPinned ids: {ids}")
接下来,进行搜索
不使用 query rules 的正常搜索
response = client.search(index="products_index", query={"multi_match": {"query": "reliable wireless charger for iPhone","fields": [ "name^5", "description" ]}
})pretty_response(response)
创建 query rules
我们分别假设,我们知道我们的用户来自哪个国家/地区(可能通过 IP 地址或登录的用户帐户信息进行地理位置定位)。 现在,我们希望创建查询规则,以便当人们搜索包含短语 “wireless charger (无线充电器)” 的任何内容时,根据该信息增强无线充电器的性能。
client.query_ruleset.put(ruleset_id="promotion-rules", rules=[{"rule_id": "us-charger","type": "pinned","criteria": [{"type": "contains","metadata": "my_query","values": ["wireless charger"]},{"type": "exact","metadata": "country","values": ["us"]}],"actions": {"ids": ["us1"]}},{"rule_id": "uk-charger","type": "pinned","criteria": [{"type": "contains","metadata": "my_query","values": ["wireless charger"]},{"type": "exact","metadata": "country","values": ["uk"]}],"actions": {"ids": ["uk1"]}}])
为了使这些规则匹配,必须满足以下条件之一:
- my_query 包含字符串 “wireless charger” 并且 country “us”
- my_query 包含字符串 “wireless charger” 并且 country 为 “uk”
我们也可以使用 API 查看我们的规则集(使用另一个 Pretty_ruleset 函数以提高可读性):
response = client.query_ruleset.get(ruleset_id="promotion-rules")
pretty_ruleset(response)
response = client.search(index="products_index", query={"rule_query": {"organic": {"multi_match": {"query": "reliable wireless charger for iPhone","fields": [ "name^5", "description" ]}},"match_criteria": {"my_query": "reliable wireless charger for iPhone","country": "us"},"ruleset_id": "promotion-rules"}
})pretty_response(response)
整个 notebook 的源码可以在地址下载:https://github.com/liu-xiao-guo/semantic_search_es/blob/main/search_using_query_rules.ipynb
相关文章:

Elasticsearch:使用查询规则(query rules)进行搜索
在之前的文章 “Elasticsearch 8.10 中引入查询规则 - query rules”,我们详述了如何使用 query rules 来进行搜索。这个交互式笔记本将向你介绍如何使用官方 Elasticsearch Python 客户端来使用查询规则。 你将使用 query rules API 将查询规则存储在 Elasticsearc…...

Java核心设计模式:代理设计模式
一、生活中常见的代理案例 房地产中介:客户手里没有房源信息,找一个中介帮忙商品代购:代理者一般有好的资源渠道,降低购物成本(如海外代购,自己不用为了买东西出国) 二、为什么要使用代理 对…...

JSP编程
JSP编程 您需要理解在JSP API的类和接口中定义的用于创建JSP应用程序的各种方法的用法。此外,还要了解各种JSP组件,如在前一部分中学习的JSP动作、JSP指令及JSP脚本。JSP API中定义的类提供了可借助隐式对象通过JSP页面访问的方法。 1. JSP API的类 JSP API是一个可用于创建…...

【Flink入门修炼】1-1 为什么要学习 Flink?
流处理和批处理是什么? 什么是 Flink? 为什么要学习 Flink? Flink 有什么特点,能做什么? 本文将为你解答以上问题。 一、批处理和流处理 早些年,大数据处理还主要为批处理,一般按天或小时定时处…...
刘谦龙年春晚魔术模拟
守岁共此时 代码 直接贴代码了,异常处理有点问题,正常流程能跑通 package com.yuhan.snginx.util.chunwan;import java.util.*;/*** author yuhan* since 2024/02/10*/ public class CWMS {static String[] num {"A", "2", &quo…...

re:从0开始的CSS学习之路 9. 盒子水平布局
0. 写在前面 过年也不能停止学习,一停下就难以为继,实属不应 1. 盒子的水平宽度 当一个盒子出现在另一个盒子的内容区时,该盒子的水平宽度“必须”等于父元素内容区的宽度 盒子水平宽度: margin-left border-left padding-lef…...

【MySQL基础】:深入探索DQL数据库查询语言的精髓(上)
🎥 屿小夏 : 个人主页 🔥个人专栏 : MySQL从入门到进阶 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一. DQL1.1 基本语法1.2 基础查询1.3 条件查询1.3 聚合函数 🌤️ 全篇…...

JavaScript实现轮播图方法
效果图 先来看下效果图,嫌麻烦就不用具体图片来实现了,主要是理清思路。(自动轮播,左右按钮切换图片,小圆点切换图片,鼠标移入暂停轮播,鼠标移出继续轮播) HTML 首先是html内容&am…...
Web课程学习笔记--jsonp的原理与简单实现
jsonp的原理与简单实现 原理 由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数&…...

第78讲 修改密码
系统管理实现 修改密码实现 前端 modifyPassword.vue: <template><el-card><el-formref"formRef":model"form":rules"rules"label-width"150px"><el-form-item label"用户名:&quo…...

Docker 容器网络:C++ 客户端 — 服务器应用程序。
一、说明 在下面的文章中, 将向您概述 docker 容器之间的通信。docker 通信的验证将通过运行 C 客户端-服务器应用程序和标准“ping”命令来执行。将构建并运行两个单独的 Docker 映像。 由于我会关注 docker 网络方面,因此不会提供 C 详细信息。…...

Android 识别车牌信息
打开我们心爱的Android Studio 导入需要的资源 gradle //开源车牌识别安卓SDK库implementation("com.github.HyperInspire:hyperlpr3-android-sdk:1.0.3")button.setOnClickListener(v -> {Log.d("Test", "");try (InputStream file getAs…...

C#在窗体正中输出文字以及输出文字的画刷使用
为了在窗体正中输出文字,需要获得输出文字区域的宽和高,这使用MeasureString方法,方法返回值为Size类型; 然后计算输出的起点的x和y坐标,就可以输出了; using System; using System.Collections.Generic; …...

二十、K8S-1-权限管理RBAC详解
目录 k8s RBAC 权限管理详解 一、简介 二、用户分类 1、普通用户 2、ServiceAccount 三、k8s角色&角色绑定 1、授权介绍: 1.1 定义角色: 1.2 绑定角色: 1.3主体(subject) 2、角色(Role和Cluster…...

【PTA|期末复习|编程题】数组相关编程题(一)
目录 7-1 乘法口诀数列 (20分) 输入格式: 输出格式: 输入样例: 输出样例: 样例解释: 代码 7-2 矩阵列平移(20分) 输入格式: 输出格式: 输入样例: 输出样例: …...

[office] 怎么在Excel2003菜单栏自定义一个选项卡 #其他#微信#知识分享
怎么在Excel2003菜单栏自定义一个选项卡 怎么在Excel2003菜单栏自定义一个选项卡 ①启动Excel2003,单击菜单栏--工具--自定义。 ②在自定义界面,我们单击命令标签,在类别中选择新菜单,鼠标左键按住新菜单,拖放到菜单栏…...
面试 JavaScript 框架八股文十问十答第六期
面试 JavaScript 框架八股文十问十答第六期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新! ⭐点赞⭐收藏⭐不迷路!⭐ 1)use strict是什么…...

【Web】小白友好的Java内存马基础学习笔记
目录 简介 文件马与内存马的比较 文件马原理 内存马原理 内存马使用场景 内存马分类 内存马注入方式 这篇文章主要是概念性的,具体技术细节不做探究,重点在祛魅。 简介 内存马(Memory Shellcode)是一种恶意攻击技术&…...
Rust猜数字游戏
Rust进阶:猜数字游戏 Rust是一门现代的系统级编程语言,注重内存安全、并发性能以及表达力。在这篇博客中,我们将深入介绍一个更加复杂的猜数字游戏代码,展示Rust语言的一些高级特性。 代码示例 以下是一个升级版的Rust猜数字游…...
.gitlab-ci.yml文件参数配置和使用
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...