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

news2025/1/24 17:51:19

了解如何使用 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-documents
    
    import 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.coloradmin.cn/o/1279304.html

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

相关文章

linux 安装go环境

下载go SDK All releases - The Go Programming Language 此处建议选择与本机windows一样的版本&#xff0c;便于调试&#xff0c;若不涉及本地windows&#xff0c;则忽略此提示 上传到linux 解压go SDK 执行下述命令进行解压 tar -xvf go1.19.linux-amd64.tar.gz 此处选择…

万能的视频格式播放器

今天博主给大家带来一款“万能”的视频播放器——VLC Media Player&#xff0c;支持的文件格式非常多&#xff0c;大家快来一起看看吧&#xff01; VLC Media Player 是一款可播放大多数格式&#xff0c;而无需安装编解码器包的媒体播放器。可以播放 MPEG-1、MPEG-2、MPEG-4、D…

Linux的基本指令(五)

目录 前言 tar指令(重要) 再次思考&#xff0c;为什么要打包和压缩呢&#xff1f; 实例&#xff1a;基于xshell进行压缩包在Windows与Linux之间的互传 实例&#xff1a;实现两个Linux系统之间的文件互传 bc指令 uname -r指令 重要的热键 关机与开机 扩展命令 shell及…

MediaPipe 3D姿态估计简明教程

姿势检测是更多地了解视频和图像中人体的重要一步。 我们现有的模型支持 2D 姿态估计已经有一段时间了&#xff0c;你们中的许多人可能已经尝试过。 今天&#xff0c;我们在 TF.js 姿势检测 API 中推出第一个 3D 模型。 3D 姿态估计为健身、医疗、动作捕捉等应用开辟了新的设计…

深度学习记录--计算图(前向后向传播)

什么是计算图&#xff1f; 从一个例子入手&#xff1a; 将函数J的计算用流程图表示出来&#xff0c;这样的流程图被称为计算图 简单来说&#xff0c;计算图是用来显示每个变量间的关系的一种图 两种传播方式 计算图有两种传播方式&#xff1a;前向传播 和 后向传播 什么是前…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于多场景模糊集和改进二阶锥方法的配电网优化调度》

这个标题涉及到配电网&#xff08;Distribution Network&#xff09;的优化调度问题&#xff0c;其中使用了两个关键的方法&#xff1a;多场景模糊集和改进二阶锥方法。 多场景模糊集&#xff1a; 多场景&#xff1a; 这可能指的是在考虑不同情景或条件下的配电网运行状态。每个…

智能优化算法应用:基于蝠鲼觅食算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于蝠鲼觅食算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于蝠鲼觅食算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蝠鲼觅食算法4.实验参数设定5.算法结果6.参考…

算力基础设施领域国家标准发布

2023 年 11 月 27 日&#xff0c;国家标准 GB/T 43331-2023《互联网数据中心&#xff08;IDC&#xff09;技术和分级要求》正式发布。这一国家标准由中国信息通信研究院&#xff08;简称“中国信通院”&#xff09;联合多家企事业单位编制&#xff0c;旨在满足当前国家算力基础…

逸学java【初级菜鸟篇】12.网络通讯编程

hi&#xff0c;我是逸尘&#xff0c;一起学java吧 目标&#xff08;任务驱动&#xff09; 请练掌网络通讯的内容。 局域网和互联网 局域网英文&#xff1a;Local Area Network&#xff0c;缩写&#xff1a;LAN&#xff0c;是指一群通过一定形式连接起来的计算机&#xff0c;…

Gradio库的安装和使用教程

目录 一、Gradio库的安装 二、Gradio的使用 1、导入Gradio库 2、创建Gradio接口 3、添加接口到Gradio应用 4、处理用户输入和模型输出 5、关闭Gradio应用界面 三、Gradio的高级用法 1、多语言支持 2、自定义输入和输出格式 3、模型版本控制 4、集成第三方库和API …

电子产品老化测试方法

电子产品老化测试是为了评估电子设备在长时间使用后的性能变化和稳定性。测试的原理是通过模拟实际情况中的磨损、环境变化等因素&#xff0c;以验证产品在实际使用中的可靠性和耐久性。以下是一些常见的电子产品老化测试方法和其应用&#xff1a; 热老化测试&#xff1a;将设备…

nodejs基于vue的社区物业缴费报修管理系统7vwc6

运行软件:vscode 前端nodejsvueElementUi 语言 node.js 框架&#xff1a;Express/koa 前端:Vue.js 数据库&#xff1a;mysql 开发软件&#xff1a;VScode/webstorm/hbuiderx均可 数据库用MySQL,后台用vue框架 基本要求&#xff1a; 1. 对项目进行详细实际的需求分析。 2. 在网…

pandas基础操作2

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

前端笔记(一):HTML5 入门学习

前言&#xff1a; 在完成 Java 的 SpringBoot 学习并练习了几个项目后&#xff0c;出于对编程的兴趣和没有组织的局限性&#xff0c;为了开发一些个人的小项目&#xff0c;我将开始前端部分的学习&#xff0c;预计会学到 Vue 框架&#xff0c;同时会把自己的学习笔记发布成博客…

赤龙ERP项目

目录 ERP简介 &#xff08;1&#xff09;软件永久免费、持续迭代、gitee开源&#xff0c;github开源 &#xff08;2&#xff09;实现主流程的业务和财务闭环 &#xff08;3&#xff09;完备的文档&#xff0c;易于部署和二次开发 技术与平台 SpringBoot2MySQLRedisJDK1.8Tom…

鸿蒙是Android套壳么,当然不是,ArkTS还是很有意思的

前段时间看新闻&#xff0c;说是明年开始鸿蒙就要和andorid脱钩了。 大概就是这样的&#xff1a; 看到这个&#xff0c;我兴趣就来了。我有个华为P30&#xff0c;升级过鸿蒙系统&#xff0c;用起来也没啥变化&#xff0c;兼容andorid应用&#xff0c;然后就是开机去掉了Powere…

多表查询与子查询

问题的引出&#xff1a; 这里有一个留言板&#xff0c;其中一条评论包含了商品名称good&#xff08;商品表&#xff09;&#xff0c;留言content(留言表)。 那么请问如将这个评论从数据库查询出来&#xff1f;这就涉及到了多表查询。 多表查询是指基于两个和两个以上的表查询.…

mediapipe+opencv实现保存图像中的人脸,抹去其他信息

mediapipeopencv MediaPipe本身不提供图像处理功能&#xff0c;它主要用于检测和跟踪人脸、手势、姿势等。如果您想要从图像中仅提取人脸主要信息并去除其他信息. # codingutf-8 """project: teatAuthor&#xff1a;念卿 刘file&#xff1a; test.pydate&…

【KPDK】概述

DPDK的主要目标是为数据平面应用程序中的快速数据包处理提供一个简单、完整的框架。用户可以使用代码来理解所采用的一些技术&#xff0c;构建原型或添加自己的协议栈。可提供使用DPDK的替代生态系统选项。 DPDK框架通过创建环境抽象层&#xff08;EAL&#xff09;为特定环境创…

LeetCode Hot100 169.多数元素

题目&#xff1a; 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 方法一&#xff1a;哈希表 ​ class Solution {public int…