结构化文档推送Demo

Push 推送数据方式,主要是预先生成符合我们规定格式的待推送数据集合,最后在调用Push方法时,将这些数据集合一次性批量推送到应用中。

相关依赖

使用SDK上传文件所需填下如下的依赖:

BaseRequest参考:Python client 示例

<dependency>
    <groupId>com.aliyun.opensearch</groupId>
    <artifactId>aliyun-sdk-opensearch</artifactId>
    <version>6.0.0</version>
</dependency>
pip install alibabacloud_tea_util 
pip install alibabacloud_opensearch_util
pip install alibabacloud_credentials
V3.4.1 (2021-05-11)
下载地址: https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20230719/mxik/opensearch-sdk-php-release-v3.4.1.zip

Push Demo 样例代码

注意

  • 推送的数据集合必须要符合我们规定的数据集合格式才行,可参考应用控制台->上传文件->参考样例数据,文件中的数据集合格式。

  • 也可以在程序中通过JSONObject 及 JSONArray对象,预先拼接生成符合我们规定格式的数据集合,再调用Push方法一次性将这些数据集合批量推送到应用中。

  • 批量推送文档个数不能太大,不能超过我们规定限制,否则可能会导致推送报错。

add操作

import java.util.HashMap;
import java.util.Map;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;


import com.aliyun.opensearch.OpenSearchClient;
import com.aliyun.opensearch.sdk.generated.OpenSearch;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchClientException;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchException;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchResult;


/**
 * 文档添加/更新demo
 */
public class testPushDemo {


    private static String appName = "替换为应用名称";
    private static String accesskey = "替换accesskey";
    private static String secret = "替换secret";
    private static String host = "替换应用的API访问地址";
    private static String path = "/apps/%s/actions/knowledge-bulk";


    public static void main(String[] args) {


        String appPath = String.format(path, appName);


        //创建并构造OpenSearch对象
        OpenSearch openSearch = new OpenSearch(accesskey, secret, host);
        //创建OpenSearchClient对象,并以OpenSearch对象作为构造参数
        OpenSearchClient openSearchClient = new OpenSearchClient(openSearch);


        //单个doc构建
        JSONObject oneRequest = new JSONObject();
        oneRequest.put("cmd", "ADD");
        JSONObject fields = new JSONObject();
        fields.put("id", "测试文档的id");
        fields.put("title", "测试文档的标题");
        fields.put("url", "测试文档对应来源的url链接");
        fields.put("content", "测试文档的内容");
        fields.put("category", "测试文档的类目");
        oneRequest.put("fields", fields);


        //可以同时添加多条数据
        JSONArray request = new JSONArray();
        request.add(oneRequest);


        Map<String, String> params = new HashMap<String, String>() {{
            put("format", "full_json");
            put("_POST_BODY", request.toJSONString());
        }};
        try {
            OpenSearchResult openSearchResult = openSearchClient.callAndDecodeResult(appPath, params, "POST");
            //打印返回结果
            System.out.println(openSearchResult.getResult());
        } catch (OpenSearchException e) {
            e.printStackTrace();
        } catch (OpenSearchClientException e) {
            e.printStackTrace();
        }
    }
}
# -*- coding: utf-8 -*-

import time, os
from typing import Dict, Any
from Tea.exceptions import TeaException
from Tea.request import TeaRequest
from alibabacloud_tea_util import models as util_models
from BaseRequest import Config, Client


class LLMDocumentPush:
    def __init__(self, config: Config):
        self.Clients = Client(config=config)
        self.runtime = util_models.RuntimeOptions(
            connect_timeout=10000,
            read_timeout=10000,
            autoretry=False,
            ignore_ssl=False,
            max_idle_conns=50,
            max_attempts=3
        )
        self.header = {}

    def docBulk(self, app_name: str,doc_content: list) -> Dict[str, Any]:
        try:
            response = self.Clients._request(method="POST",
                                             pathname=f'/v3/openapi/apps/{app_name}/actions/knowledge-bulk',
                                             query={}, headers=self.header,
                                             body=doc_content, runtime=self.runtime)
            return response
        except Exception as e:
            print(e)

if __name__ == "__main__":
    # 配置统一的请求入口 注意:host需要去掉http://
    endpoint = "<endpoint>"
    # 支持 protocol 配置 HTTPS/HTTP
    endpoint_protocol = "HTTP"
    # 用户识别信息
    # 从环境变量读取配置的AccessKey ID和AccessKey Secret,
    # 运行代码示例前必须先配置环境变量,参考文档上面“配置环境变量”步骤
    access_key_id = os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_ID")
    access_key_secret = os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
    # 支持 type 配置 sts/access_key 鉴权. 其中 type 默认为 access_key 鉴权. 使用 sts 可配置 RAM-STS 鉴权.
    # 备选参数为:  sts 或者 access_key
    auth_type = "access_key"
    # 如果使用 RAM-STS 鉴权, 请配置 security_token, 可使用 阿里云 AssumeRole 获取 相关 STS 鉴权结构.
    security_token = "<security_token>"
    # 配置请求使用的通用信息.
    # 注意:security_token和type参数,如果不是子账号需要省略
    Configs = Config(endpoint=endpoint, access_key_id=access_key_id, access_key_secret=access_key_secret,
                     security_token=security_token, type=auth_type, protocol=endpoint_protocol)
    # 创建 opensearch 智能问答版实例
    # 请将<应用名称>替换为您创建的智能问答版实例名称
    ops = LLMDocumentPush(Configs)
    app_name = "<应用名称>"

    # ---------------  智能问答版结构化文档推送 ---------------

    document = [
        {
            "fields": {
                "id": "1",
                "title": "产品优势",
                "url": "https://help.aliyun.com/document_detail/464900.html",
                "content": "行业算法版智能内置丰富的定制化算法模型,并结合不同行业搜索特点,推出行业召回、排序算法,保障更优搜索效果。灵活、可定制开发者可基于自身业务特性与数据,定制相应的算法模型、应用结构、数据处理、查询分析、排序等配置,满足个性化搜索需求,提升搜索结果点击率,实现业务快速迭代,极大缩短需求上线的周期。安全、稳定提供7×24小时的运行维护,并以在线工单和电话报障等方式提供技术支持,具备完善的故障监控、自动告警、快速定位等一系列故障应急响应机制。基于阿里云的AccessKeyId和AccessKeySecret安全加密对,从访问接口上进行权限控制和隔离,保证用户级别的数据隔离,用户数据安全有保障。数据冗余备份,保证数据不会丢失。弹性伸缩具备弹性扩容能力,用户可根据需要自行扩展或缩减所使用的资源。丰富的外围功能支持热搜、底纹、下拉提示、统计报表等一系列搜索外围功能,方便用户展示及分析。开箱即用无需运维部署集群,快速一站式接入搜索服务高性能检索版高吞吐单表支持万级别的写入TPS,秒级更新。安全、稳定提供7×24小时的运行维护,并以在线工单和电话报障等方式提供技术支持,具备完善的故障监控、自动告警、快速定位等一系列故障应急响应机制。基于阿里云的AccessKeyId和AccessKeySecret安全加密对,从访问接口上进行权限控制和隔离,保证用户级别的数据隔离,用户数据安全有保障。数据冗余备份,保证数据不会丢失。弹性伸缩具备弹性扩容能力,用户可根据需要自行扩展或缩减所使用的资源。开箱即用无需运维部署集群,快速一站式接入搜索服务向量检索版稳定底层采用c++实现,经过十多年的发展,支撑了多个核心业务,非常稳定,非常适用于对稳定性要求较高的核心搜索场景。高效分布式搜索引擎,可以高效的支持海量数据的检索,同时也支持数据的实时更新(秒级生效),非常适用于对查询耗时敏感、时效性要求高的搜索场景。低成本支持多种索引压缩策略,同时支持多值索引加载测试,能够以较低的成本满足用户的查询需求。向量算法支持各种非结构化数据(如语音、图片、视频,语言文字、行为等)向量检索。SQL查询支持SQL查询语法,支持多表在线join,提供丰富的内置UDF函数和UDF函数定制机制,以满足不同用户的检索需求。在运维系统中我们已经集成SQL studio,方便用户进行SQL开发和测试。召回引擎版稳定底层采用c++实现,经过十多年的发展,支撑了多个核心业务,非常稳定,非常适用于对稳定性要求较高的核心搜索场景。高效问天引擎是一个分布式搜索引擎,可以高效的支持海量数据的检索,同时也支持数据的实时更新(秒级生效),非常适用于对查询耗时敏感、时效性要求高的搜索场景。低成本问天引擎支持多种索引压缩策略,同时支持多值索引加载测试,能够以较低的成本满足用户的查询需求。功能丰富问天引擎支持多种分析器类型、多种索引类型、强大的查询语法,能够很好的满足用户的检索需求。同时我们还提供插件机制,方便用户定制自己的业务处理逻辑。SQL查询问天引擎支持SQL查询语法,支持多表在线join,提供丰富的内置UDF函数和UDF函数定制机制,以满足不同用户的检索需求。在运维系统中我们即将集成SQL studio,方便用户进行SQL开发和测试。",
                "category": "opensearch",
                "timestamp": 1691722088645,
                "score": 0.8821945219723084
            },
            "cmd": "ADD"
        },
        {
            "fields": {
                "id": "2",
                "title": "应用场景",
                "url": "https://help.aliyun.com/document_detail/464901.html",
                "content": "行业算法版:版本特性:内置行业查询语义理解、机器学习算法等能力,同时支持轻量化定制模型、及搜索引导功能,助力开发者快速搭建智能搜索服务。<br/><img src=\"https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/4685770861/p622804.png\" width=300>典型业务场景:电商零售智能搜索、内容社区智能搜索、游戏智能搜索、教育搜题等适用客户:开箱即用,适合有智能搜索诉求的中小企业及开发者高性能检索版版本特性:大数据检索性能深度优化,实现秒级响应,实时查询能力,支持一站式快速搭建订单、优惠券、物流、保单等大数据检索场景搜索业务。<br/><img src=\"https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/3685770861/p622799.png\" width=300>典型业务场景:订单检索、优惠券检索、物流检索、保单检索等;适用客户:开箱即用,适合有高性能检索诉求的中小企业及开发者向量检索版版本特性:大规模分布式高性能公有云向量检索解决方案,支持多种检索算法,实现精度和性能之间的平衡,支持索引流式构建、即增即查。<br/><img src=\"https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/4685770861/p622805.png\" width=300>典型业务场景:图片搜索、音视频检索、NLP向量检索、智能问答等适用客户:适合向量规模较大,需灵活开发的企业及开发者召回引擎版版本特性:为用户提供高性能、低成本、简单易用的大规模在线搜索服务。可灵活支持业务需求的定制开发,及搜索算法快速迭代。<br/><img src=\"https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/4685770861/p622806.png\" width=300>典型业务场景:企业信息检索、标签检索、金融研报检索、智能检索等适用客户:适合数据规模较大,需灵活开发的企业及开发者。",
                "category": "opensearch",
                "timestamp": 1691722088646,
                "score": 0.8993507402088953
            },
            "cmd": "ADD"
        }
    ]

    # 删除记录
    deletedocument = {"cmd": "DELETE", "fields": {"id": 2}}
    documents = document
    res5 = ops.docBulk(app_name=app_name, doc_content=documents)
    print(res5)
<?php
  
require_once($path . "/OpenSearch/Autoloader/Autoloader.php");

use OpenSearch\Client\OpenSearchClient;

// 用户识别信息
// 从环境变量读取配置的AccessKey ID和AccessKey Secret,
// 运行代码示例前必须先配置环境变量,参考文档上面“配置环境变量”步骤
// 替换对应的access key id
$accessKeyId = getenv('ALIBABA_CLOUD_ACCESS_KEY_ID');
//替换对应的access secret
$secret = getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
$endPoint = '<替换为 endpoint>';
$appName = '<替换为 应用名称>';
$options = array('debug' => true);
$requestBody = "[
 {
  \"fields\":{
   \"id\":\"15739\",
   \"title\":\"产品优势\",
   \"url\":\"https://help.aliyun.com/document_detail/464900.html\",
   \"content\":\"行业算法版:版本特性:内置行业查询语义理解、机器学习算法等能力,同时支持轻量化定制模型、及搜索引导功能,助力开发者快速搭建智能搜索服务。<br/><img src=\"https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/4685770861/p622804.png\"width=300>典型业务场景:电商零售智能搜索、内容社区智能搜索、游戏智能搜索、教育搜题等适用客户:开箱即用,适合有智能搜索诉求的中小企业及开发者高性能检索版版本特性:大数据检索性能深度优化,实现秒级响应,实时查询能力,支持一站式快速搭建订单、优惠券、物流、保单等大数据检索场景搜索业务。\",
   \"category\":\"opensearch\",
   \"timestamp\":1691722088646,\"score\":0.8993507402088953},
   \"cmd\":\"ADD\"
 }
]";

$client = new OpenSearchClient($accessKeyId, $secret, $endPoint, $options);

$uri = "/apps/{$appName}/actions/knowledge-bulk";

try{
    $ret = $client->post($uri, $requestBody);
    print_r(json_decode($ret->result, true));
}catch (\Throwable $e) {
    print_r($e);
}

说明
  • 目前仅支持ADD操作,更新文档需要通过ADD指令,带入记录全字段内容,否则,由于ADD是覆盖操作,会造成部分未携带的字段内容为空。

  • title字段最大长度为64字符,超过该长度会导致文档写入不成功。

delete操作

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;


import com.aliyun.opensearch.OpenSearchClient;
import com.aliyun.opensearch.sdk.generated.OpenSearch;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchClientException;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchException;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchResult;


/**
 * 文档删除demo
 */
public class testDeleteDemo {


    private static String appName = "替换为应用名称";
    private static String accesskey = "替换accesskey";
    private static String secret = "替换secret";
    private static String host = "替换应用的API访问地址";
    private static String path = "/apps/%s/actions/knowledge-bulk";


    public static void main(String[] args) {


        String appPath = String.format(path, appName);


        //创建并构造OpenSearch对象
        OpenSearch openSearch = new OpenSearch(accesskey, secret, host);
        //创建OpenSearchClient对象,并以OpenSearch对象作为构造参数
        OpenSearchClient openSearchClient = new OpenSearchClient(openSearch);


        //单个删除doc构建
        JSONObject oneRequest = new JSONObject();
        oneRequest.put("cmd", "DELETE");
        JSONObject fields = new JSONObject();
        fields.put("id", "测试删除文档的id");
        oneRequest.put("fields", fields);


        //可以同时添加多条删除的数据
        JSONArray request = new JSONArray();
        request.add(oneRequest);


        Map<String, String> params = new HashMap<String, String>() {{
            put("format", "full_json");
            put("_POST_BODY", request.toJSONString());
        }};
        try {
            OpenSearchResult openSearchResult = openSearchClient.callAndDecodeResult(appPath, params, "POST");
            //打印返回结果
            System.out.println(openSearchResult.getResult());
        } catch (OpenSearchException e) {
            e.printStackTrace();
        } catch (OpenSearchClientException e) {
            e.printStackTrace();
        }
    }
}
# -*- coding: utf-8 -*-

import time, os
from typing import Dict, Any
from Tea.exceptions import TeaException
from Tea.request import TeaRequest
from alibabacloud_tea_util import models as util_models
from BaseRequest import Config, Client


class LLMDocumentPush:
    def __init__(self, config: Config):
        self.Clients = Client(config=config)
        self.runtime = util_models.RuntimeOptions(
            connect_timeout=10000,
            read_timeout=10000,
            autoretry=False,
            ignore_ssl=False,
            max_idle_conns=50,
            max_attempts=3
        )
        self.header = {}

    def docBulk(self, app_name: str,doc_content: list) -> Dict[str, Any]:
        try:
            response = self.Clients._request(method="POST",
                                             pathname=f'/v3/openapi/apps/{app_name}/actions/knowledge-bulk',
                                             query={}, headers=self.header,
                                             body=doc_content, runtime=self.runtime)
            return response
        except Exception as e:
            print(e)

if __name__ == "__main__":
    # 配置统一的请求入口 注意:host需要去掉http://
    endpoint = "<endpoint>"
    # 支持 protocol 配置 HTTPS/HTTP
    endpoint_protocol = "HTTP"
    # 用户识别信息
    # 从环境变量读取配置的AccessKey ID和AccessKey Secret,
    # 运行代码示例前必须先配置环境变量,参考文档上面“配置环境变量”步骤
    access_key_id = os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_ID")
    access_key_secret = os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
    # 支持 type 配置 sts/access_key 鉴权. 其中 type 默认为 access_key 鉴权. 使用 sts 可配置 RAM-STS 鉴权.
    # 备选参数为:  sts 或者 access_key
    auth_type = "access_key"
    # 如果使用 RAM-STS 鉴权, 请配置 security_token, 可使用 阿里云 AssumeRole 获取 相关 STS 鉴权结构.
    security_token = "<security_token>"
    # 配置请求使用的通用信息.
    # 注意:security_token和type参数,如果不是子账号需要省略
    Configs = Config(endpoint=endpoint, access_key_id=access_key_id, access_key_secret=access_key_secret,
                     security_token=security_token, type=auth_type, protocol=endpoint_protocol)
    # 创建 opensearch 智能问答版实例
    # 请将<应用名称>替换为您创建的智能问答版实例名称
    ops = LLMDocumentPush(Configs)
    app_name = "<应用名称>"

    # 删除记录
    deletedocument = {"cmd": "DELETE", "fields": {"id": 2}}
    documents = document
    res5 = ops.docBulk(app_name=app_name, doc_content=documents)
    print(res5)