Azure Machine Learning - 使用 Azure SDK 进行全文搜索

了解如何使用 Azure SDK 中的 Azure.Search.Documents 客户端库创建、加载和查询使用示例数据的搜索索引,实现全文搜索。 全文搜索使用 Apache Lucene 进行索引和查询,使用 BM25 排名算法对结果进行评分。

关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。

file

环境准备

  • 具有活动订阅的 Azure 帐户。 免费创建帐户。

  • Azure AI 搜索服务。 如果还没有,请创建服务。

  • API 密钥和服务终结点:

    登录到 Azure 门户并查找你的搜索服务。

    在“概述”中,复制 URL 并将其保存到记事本以供后续步骤使用。 示例终结点可能类似于 https://mydemo.search.windows.net

    在“密钥”中,复制并保存管理密钥,以获取创建和删除对象的完整权限。 有两个可互换的主要密钥和辅助密钥。 选择其中一个。

file

创建、加载并查询索引

选择下一步要使用的编程语言。 Azure.Search.Documents 客户库在面向 .NET、Python、Java 和 JavaScript 的 Azure SDK 中均可使用。
以Python为例:

使用 azure-search-documents 库构建 Jupyter Notebook,用于创建、加载和查询索引。 或者,可以下载并运行已完成的 Jupyter Python 笔记本,或按照这些步骤创建自己的笔记本。

设置你的环境

我们使用以下工具创建了本快速入门。

  • 带有 Python 扩展的 Visual Studio Code(或等效的 IDE),Python 版本为 3.7 或更高

  • 用于 Python 的 Azure SDK 中的 azure-search-documents 包

连接到 Azure AI 搜索

在此任务中,创建笔记本、加载库并设置客户端。

  1. 在 Visual Studio Code 中创建新的 Python3 笔记本:

    1. 按 F1 并搜索“Python 选择解释器”,然后选择 Python 3.7 版本或更高版本。
    2. 再次按 F1 并搜索“创建:新的 Jupyter Notebook”。 应在编辑器中打开一个空的无标题 .ipynb 文件,为第一个条目做好准备。
  2. 在第一个单元格中,从用于 Python 的 Azure SDK 加载库,包括 azure-search-documents。

    %pip install azure-search-documents --pre
    %pip show azure-search-documentsimport os
    from azure.core.credentials import AzureKeyCredential
    from azure.search.documents.indexes import SearchIndexClient 
    from azure.search.documents import SearchClient
    from azure.search.documents.indexes.models import (ComplexField,CorsOptions,SearchIndex,ScoringProfile,SearchFieldDataType,SimpleField,SearchableField
    )
    
  3. 添加第二个单元格并粘贴连接信息。 此单元格还设置了将用于执行特定操作的客户端:用于创建索引的 SearchIndexClient,以及用于查询索引的 SearchClient。

    由于代码为你生成了 URI,因此只需在服务名称属性中指定搜索服务名称。

    service_name = "<YOUR-SEARCH-SERVICE-NAME>"
    admin_key = "<YOUR-SEARCH-SERVICE-ADMIN-API-KEY>"index_name = "hotels-quickstart"# Create an SDK client
    endpoint = "https://{}.search.windows.net/".format(service_name)
    admin_client = SearchIndexClient(endpoint=endpoint,index_name=index_name,credential=AzureKeyCredential(admin_key))search_client = SearchClient(endpoint=endpoint,index_name=index_name,credential=AzureKeyCredential(admin_key))
    
  4. 在第三个单元格中,运行 delete_index 操作以清除所有现有的 hotels-quickstart 索引服务。 通过删除索引,可以创建另一个同名的 hotels-quickstart 索引。

    try:result = admin_client.delete_index(index_name)print ('Index', index_name, 'Deleted')
    except Exception as ex:print (ex)
    
  5. 运行每个步骤。

创建索引

必需的索引元素包括名称、字段集合和唯一标识每个搜索文档的文档键。 字段集合定义逻辑搜索文档的结构,用于加载数据和返回结果。

在字段集合中,每个字段都具有一个名称、类型和确定字段用法的属性(例如,该字段在搜索结果是否可全文搜索、可筛选或可检索)。 在索引中,必须将一个 Edm.String 类型的字段指定为文档标识的键。

此索引名为“hotels-quickstart”,使用下面所示的字段定义。 它是其他演练中使用的一个更大 Hotels 索引的子集。 为简明起见,本快速入门已对其进行修整。

  1. 在下一个单元格中,将以下示例粘贴到某个单元格以提供架构。

    # Specify the index schema
    name = index_name
    fields = [SimpleField(name="HotelId", type=SearchFieldDataType.String, key=True),SearchableField(name="HotelName", type=SearchFieldDataType.String, sortable=True),SearchableField(name="Description", type=SearchFieldDataType.String, analyzer_name="en.lucene"),SearchableField(name="Description_fr", type=SearchFieldDataType.String, analyzer_name="fr.lucene"),SearchableField(name="Category", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),SearchableField(name="Tags", collection=True, type=SearchFieldDataType.String, facetable=True, filterable=True),SimpleField(name="ParkingIncluded", type=SearchFieldDataType.Boolean, facetable=True, filterable=True, sortable=True),SimpleField(name="LastRenovationDate", type=SearchFieldDataType.DateTimeOffset, facetable=True, filterable=True, sortable=True),SimpleField(name="Rating", type=SearchFieldDataType.Double, facetable=True, filterable=True, sortable=True),ComplexField(name="Address", fields=[SearchableField(name="StreetAddress", type=SearchFieldDataType.String),SearchableField(name="City", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),SearchableField(name="StateProvince", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),SearchableField(name="PostalCode", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),SearchableField(name="Country", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),])]
    cors_options = CorsOptions(allowed_origins=["*"], max_age_in_seconds=60)
    scoring_profiles = []
    suggester = [{'name': 'sg', 'source_fields': ['Tags', 'Address/City', 'Address/Country']}]
    
  2. 在另一个单元格中构建请求。 此 create_index 请求以搜索服务的索引集合为目标,并基于在上一单元格中提供的索引架构创建 SearchIndex。

    index = SearchIndex(name=name,fields=fields,scoring_profiles=scoring_profiles,suggesters = suggester,cors_options=cors_options)try:result = admin_client.create_index(index)print ('Index', result.name, 'created')
    except Exception as ex:print (ex)
    
  3. 运行每个步骤。

加载文档

若要加载文档,请使用操作类型(上传、合并上传等)的索引操作来创建文档集合。 文档源自 GitHub 上的 HotelsData。

  1. 在新单元格中,提供符合索引架构的四个文档。 指定每个文档的上传操作。

    documents = [{"@search.action": "upload","HotelId": "1","HotelName": "Secret Point Motel","Description": "The hotel is ideally located on the main commercial artery of the city in the heart of New York. A few minutes away is Time's Square and the historic centre of the city, as well as other places of interest that make New York one of America's most attractive and cosmopolitan cities.","Description_fr": "L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus attractives et cosmopolites de l'Amérique.","Category": "Boutique","Tags": [ "pool", "air conditioning", "concierge" ],"ParkingIncluded": "false","LastRenovationDate": "1970-01-18T00:00:00Z","Rating": 3.60,"Address": {"StreetAddress": "677 5th Ave","City": "New York","StateProvince": "NY","PostalCode": "10022","Country": "USA"}},{"@search.action": "upload","HotelId": "2","HotelName": "Twin Dome Motel","Description": "The hotel is situated in a  nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts.","Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.","Category": "Boutique","Tags": [ "pool", "free wifi", "concierge" ],"ParkingIncluded": "false","LastRenovationDate": "1979-02-18T00:00:00Z","Rating": 3.60,"Address": {"StreetAddress": "140 University Town Center Dr","City": "Sarasota","StateProvince": "FL","PostalCode": "34243","Country": "USA"}},{"@search.action": "upload","HotelId": "3","HotelName": "Triple Landscape Hotel","Description": "The Hotel stands out for its gastronomic excellence under the management of William Dough, who advises on and oversees all of the Hotel's restaurant services.","Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.","Category": "Resort and Spa","Tags": [ "air conditioning", "bar", "continental breakfast" ],"ParkingIncluded": "true","LastRenovationDate": "2015-09-20T00:00:00Z","Rating": 4.80,"Address": {"StreetAddress": "3393 Peachtree Rd","City": "Atlanta","StateProvince": "GA","PostalCode": "30326","Country": "USA"}},{"@search.action": "upload","HotelId": "4","HotelName": "Sublime Cliff Hotel","Description": "Sublime Cliff Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Cliff is part of a lovingly restored 1800 palace.","Description_fr": "Le sublime Cliff Hotel est situé au coeur du centre historique de sublime dans un quartier extrêmement animé et vivant, à courte distance de marche des sites et monuments de la ville et est entouré par l'extraordinaire beauté des églises, des bâtiments, des commerces et Monuments. Sublime Cliff fait partie d'un Palace 1800 restauré avec amour.","Category": "Boutique","Tags": [ "concierge", "view", "24-hour front desk service" ],"ParkingIncluded": "true","LastRenovationDate": "1960-02-06T00:00:00Z","Rating": 4.60,"Address": {"StreetAddress": "7400 San Pedro Ave","City": "San Antonio","StateProvince": "TX","PostalCode": "78216","Country": "USA"}}
    ]
    
  2. 在另一个单元格中构建请求。 此 upload_documents 请求以 hotels-quickstart 索引的文档集合为目标,将在上一步骤中提供的文档推送到 Azure AI 搜索索引。

    try:result = search_client.upload_documents(documents=documents)print("Upload of new document succeeded: {}".format(result[0].succeeded))
    except Exception as ex:print (ex.message)
    
  3. 运行每个步骤,将文档推送到搜索服务中的索引。

搜索索引

此步骤说明如何使用 search.client 类的 search 方法来查询索引。

  1. 下面的步骤执行空搜索 (search=*),返回任意文档的未排名列表(搜索分数 = 1.0)。 由于没有条件,因此所有文档都包含在结果中。 此查询仅输出每个文档中的两个字段。 它还会添加 include_total_count=True 以获取结果中所有文档 (4) 的计数。

    results = search_client.search(search_text="*", include_total_count=True)print ('Total Documents Matching Query:', results.get_count())
    for result in results:print("{}: {}".format(result["HotelId"], result["HotelName"]))
    
  2. 下一个查询将整个术语添加到搜索表达式 (“wifi”)。 此查询指定结果仅包含 select 语句中的那些字段。 限制返回的字段可最大程度地减少通过网络发回的数据量,并降低搜索延迟。

    results = search_client.search(search_text="wifi", include_total_count=True, select='HotelId,HotelName,Tags')print ('Total Documents Matching Query:', results.get_count())
    for result in results:print("{}: {}: {}".format(result["HotelId"], result["HotelName"], result["Tags"]))
    
  3. 接下来,应用筛选表达式,仅返回评分高于 4 的酒店(按降序排列)。

    results = search_client.search(search_text="hotels", select='HotelId,HotelName,Rating', filter='Rating gt 4', order_by='Rating desc')for result in results:print("{}: {} - {} rating".format(result["HotelId"], result["HotelName"], result["Rating"]))
    
  4. 添加 search_fields(一个数组),将查询匹配的范围限制为单一字段。

    results = search_client.search(search_text="sublime", search_fields=['HotelName'], select='HotelId,HotelName')for result in results:print("{}: {}".format(result["HotelId"], result["HotelName"]))
    
  5. Facet 是可用于组成 Facet 导航结构的标签。 此查询返回类别的 Facet 和计数。

    results = search_client.search(search_text="*", facets=["Category"])facets = results.get_facets()for facet in facets["Category"]:print("    {}".format(facet))
    
  6. 在此示例中,根据文档的键查找特定的文档。 当用户选择搜索结果中的文档时,你通常需要返回文档。

    result = search_client.get_document(key="3")print("Details for hotel '3' are:")
    print("Name: {}".format(result["HotelName"]))
    print("Rating: {}".format(result["Rating"]))
    print("Category: {}".format(result["Category"]))
    
  7. 在最后一个示例中,我们将使用自动完成函数。 “自动完成”通常在搜索框中使用,以便在用户在搜索框中键入时提供可能的匹配项。

    创建索引时,还会创建名为“sg”的建议器作为请求的一部分。 建议器定义指定哪些字段可用于查找建议器请求的潜在匹配。 在此示例中,这些字段是“标签”、“地址/城市”、“地址/国家/地区”。 若要模拟自动完成,请输入字母“sa”作为字符串的一部分。 SearchClient 的自动完成方法会发回可能的术语匹配。

    search_suggestion = 'sa'
    results = search_client.autocomplete(search_text=search_suggestion, suggester_name="sg", mode='twoTerms')print("Autocomplete for:", search_suggestion)
    for result in results:print (result['text'])
    

关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。

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

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

相关文章

【Spring Boot 源码学习】ApplicationContextInitializer 详解

Spring Boot 源码学习系列 ApplicationContextInitializer 详解 引言往期内容主要内容1. 初识 ApplicationContextInitializer2. 加载 ApplicationContextInitializer3. ApplicationContextInitializer 的初始化 总结 引言 书接前文《初识 SpringApplication》&#xff0c;我们…

【傻瓜级JS-DLL-WINCC-PLC交互】6.​向PLC里面装载数据变量

思路 JS-DLL-WINCC-PLC之间进行交互&#xff0c;思路&#xff0c;先用Visual Studio创建一个C#的DLL控件&#xff0c;然后这个控件里面嵌入浏览器组件&#xff0c;实现JS与DLL通信&#xff0c;然后DLL放入到WINCC里面的图形编辑器中&#xff0c;实现DLL与WINCC的通信。然后PLC与…

使用String.valueOf()的坑

说明&#xff1a;记录一次使用String.valueOf()的坑&#xff0c;以下是一段有问题的代码&#xff1a; String count String.valueOf(listData.get(0).get(0).get("count");if (StringUtils.isBlank(count) || "0".equals(count)) {result.setResult(page)…

【bat】批处理脚本大全

目录 1.概述 2.变量 3.运算符 3.2.重定向运算符 3.3.多命名运算符 3.4.管道运算符 4.命令 4.1.基本命令 4.2.参数传递 4.3.查看脚本内容 4.4.注释 4.5.日期和时间 4.6.启动脚本 4.7.调用其他bat 4.8.任务管理 4.8.1.任务列表查看 4.8.2.任务终止 4.9.文件夹 …

美容院管理系统服务预约会员小程序效果如何

美容院在美业场景中需求度较高&#xff0c;尤其女性爱美悦己消费逐年增加&#xff0c;如清洁焕肤、祛皱抗衰、激光脱毛等美容项目都有不少需求者。 互联网深入美业行业多年&#xff0c;传统线下经营模式已经很难满足当今客户消费流程&#xff0c;如品牌寻找、服务预约、到店、…

Effective Java解读

Effective Java 第一章 引言第二章 创建和销毁对象第1条&#xff1a;用静态工厂方法代替构造器第2条&#xff1a;遇到多个构造器参数时要考虑使用构建器第3条&#xff1a;用私有构造器或者枚举类型强化Singletion属性第4条&#xff1a;通过私有构造器强化不可实例化的能力第5条…

pandas基础操作2

数据读取 我们想要使用 Pandas 来分析数据&#xff0c;那么首先需要读取数据。大多数情况下&#xff0c;数据都来源于外部的数据文件或者数据库。Pandas 提供了一系列的方法来读取外部数据&#xff0c;非常全面。下面&#xff0c;我们以最常用的 CSV 数据文件为例进行介绍。 …

【LeetCode:1423. 可获得的最大点数 | 滑动窗口】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

微前端实战:打造高效、灵活的前端应用架构

文章目录 一、微前端简介二、微前端的优势1. 高度模块化2. 独立部署3. 易于扩展4. 技术栈无关5. 独立升级 三、微前端的原理四、微前端案例思路《微前端实战》编辑推荐内容简介作者简介目录前言/序言 随着互联网行业的快速发展&#xff0c;前端应用的规模和复杂度也在不断增加。…

windows11 调整鼠标灵敏度方法

首先 我们打开电脑设置 或者在 此电脑/此计算机/我的电脑 右击选择属性 然后 有的电脑 左侧菜单中 直接就有 设备 然后在设备中直接就可以找到 鼠标 选项 调整光标速度即可 如果操作系统和我的一样 可以直接搜索鼠标 然后 选择 鼠标设置 然后 调整上面的鼠标指针速度即可

论文解读--Robust lane detection and tracking with Ransac and Kalman filter

使用随机采样一致性和卡尔曼滤波的鲁棒的车道线跟踪 摘要 在之前的一篇论文中&#xff0c;我们描述了一种使用霍夫变换和迭代匹配滤波器的简单的车道检测方法[1]。本文扩展了这项工作&#xff0c;通过结合逆透视映射来创建道路的鸟瞰视图&#xff0c;应用随机样本共识来帮助消…

网络编程之套接字

端口 && IP 在学习套接字编程之前&#xff0c;我们必须了解一下前缀知识。首先是IP和端口的作用。 在这之前&#xff0c;我们要明白一件事。那就是把数据从一台主机发送到另一台主机&#xff0c;是目的吗&#xff1f;&#xff1f;&#xff1f;当然不是&#xff01;&a…

qt-C++笔记之识别点击鼠标右键、点击位置以及Qt坐标系详解

qt-C笔记之识别点击鼠标右键、点击位置以及Qt坐标系详解 文章目录 qt-C笔记之识别点击鼠标右键、点击位置以及Qt坐标系详解1.示例运行2.event->pos();详解3.event->pos()的坐标系原点4.Qt中的坐标系详解5.QMainWindow::mousePressEvent(event);详解 1.示例运行 截图时鼠…

【SpringMVC】Spring Web MVC入门(一)

文章目录 前言什么是Spring Web MVC&#xff1f;什么是MVC什么是Spring MVC&#xff1f; Spring Boot 和 Spring MVC 的区别什么是Spring Boot&#xff1f;关系和区别 Spring MVC 学习注解介绍1. SpringBootApplication2. RestController3. RequestMapping3.1 RequestMapping 使…

css所有属性介绍

文章目录 1️⃣ CSS属性介绍1.1 CSS3 动画属性&#xff08;Animation&#xff09;1.2 CSS 背景属性&#xff08;Background&#xff09;1.3 CSS 边框属性&#xff08;Border 和 Outline&#xff09;1.4 Box 属性1.5 Color 属性1.6 Content for Paged Media 属性1.7 CSS 尺寸属性…

CyclicBarrier实战应用——批量数据多线程协调异步处理(主线程执行事务回滚)

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; CCyclicBarrier实战应用——批量数据多线程协调异步处理(主线程执行事务…

Linux学习笔记之七(shell脚本的基本语法)

Shell 1、Shell脚本2、常用运算符2、特殊语法4、关于变量的一些命令4.1、echo4.2、export4.3、read4.4、declare/typeset4.5、local4.6、unset 5、基本逻辑语法5.1、if判断5.2、for循环5.3、while循环5.4、case语句 6、函数定义7、多脚本链接 1、Shell脚本 学习shell脚本开发之…

C-语言每日刷题

目录 [蓝桥杯 2015 省 A] 饮料换购 题目描述 输入格式 输出格式 输入输出样例 # [蓝桥杯 2023 省 A] 平方差 题目描述 输入格式 输出格式 输入输出样例 说明/提示 【样例说明】 [NOIP2001 普及组] 数的计算 题目描述 输入格式 输出格式 输入输出样例 说明/提示 样例 1 解释 数据…

RK3568平台开发系列讲解(Linux系统篇)netlink 监听广播信息

** 🚀返回专栏总目录 文章目录 一、什么是netlink 机制二、netlink 的使用2.1、创建 socket2.2、绑定套接字2.3、接收数据沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍如何通过 netlink 监听广播信息。 一、什么是netlink 机制 Netlink 是 Linux 内核中…

企业计算机服务器locked1勒索病毒数据恢复,locked1勒索病毒解密流程

随着计算机技术的不断发展&#xff0c;越来越多的企业走向数字化办公时代&#xff0c;计算机技术为企业的生产运营提供了有利条件&#xff0c;但也为企业带来了网络安全威胁。在本月&#xff0c;云天数据恢复中心陆续接到很多企业的求助&#xff0c;企业的速达办公软件遭到了lo…