main.tea (336 lines of code) (raw):

/** * */ import Util; import OpenSearchUtil; import Credential; type @endpoint = string type @protocol = string type @userAgent = string type @credential = Credential model Config { endpoint?: string, protocol?: string, type?: string, securityToken?: string, accessKeyId?: string, accessKeySecret?: string, userAgent?: string } init(config: Config){ if (Util.isUnset(config)) { throw { name = 'ParameterMissing', message = '\'config\' can not be unset' }; } if (Util.empty(config.type)) { config.type = 'access_key'; } var credentialConfig = new Credential.Config{ accessKeyId = config.accessKeyId, type = config.type, accessKeySecret = config.accessKeySecret, securityToken = config.securityToken, }; @credential = new Credential(credentialConfig); @endpoint = config.endpoint; @protocol = config.protocol; @userAgent = config.userAgent; } model SearchQuery { query: string(name='query', description='搜索主体,不能为空。主要支持子句有 config子句、query子句、sort子句、filter子句、aggregate子句、distinct子句 、kvpairs子句。'), fetchFields?: string(name='fetch_fields', description='表示本次查询需要召回哪些字段值,多个字段之间通过英文分号;分隔,对应控制台中的默认展示字段功能。默认使用全部可展示字段。'), qp?: string(name='qp', description='指定要使用的查询分析规则,多个规则使用英文逗号,分隔。默认使用已上线规则'), disable?: string(name='disable', description='关闭指定已生效的参数功能。'), firstRankName?: string(name='first_rank_name', description='设置粗排表达式名字。'), secondRankName?: string(name='second_rank_name', description='设置精排表达式名字。'), userId?: string(name='user_id', description='用来标识发起当前搜索请求的终端用户。该值可以设置为下列值,优先级从高到低:1. 终端用户的长登录会员ID;2. 终端用户的移动设备imei标识;3. 终端用户的client_ip'), abtest?: string(name='abtest', description='使用A/B Test功能时需要设置该参数。'), categoryPrediction?: string(name='category_prediction', description='通过类目预测功能搜索时需要设置该参数。'), rawQuery?: string(name='raw_query', description='终端用户输入的query,用于类目预测相关模型训练。'), summary?: string(name='summary', description='搜索结果摘要配置,可以指定某些字段进行飘红、截断等操作。'), } model SearchRequestModel { headers?: map[string]string(description='headers', name='headers'), query: SearchQuery(description='query', name='query') } model SearchResponseModel { headers?: map[string]string(description='headers', name='headers'), body: SearchResponse(description='body', name='body') } /** * 系统提供了丰富的搜索语法以满足用户各种场景下的搜索需求。 */ async function searchEx(appName: string, request: SearchRequestModel, runtime: Util.RuntimeOptions): SearchResponseModel { return _request('GET', `/v3/openapi/apps/${appName}/search`, request.query, request.headers, null, runtime); } /** * 系统提供了丰富的搜索语法以满足用户各种场景下的搜索需求。 */ async function search(appName: string, request: SearchRequestModel): SearchResponseModel { var runtime = new Util.RuntimeOptions{ connectTimeout = 5000, readTimeout = 10000, autoretry = false, ignoreSSL = false, maxIdleConns = 50, }; return searchEx(appName, request, runtime); } model SuggestQuery { query: string(name='query', description='搜索关键词(包含中文需进行urlencode编码)'), hit?: integer(name='hit', description='下拉提示条数', minimum=1, maximum=10, default=10), } model SuggestRequestModel { headers?: map[string]string(description='headers', name='headers'), query: SuggestQuery(description='query', name='query') } model SuggestResponseModel { headers?: map[string]string(description='headers', name='headers'), body: SuggestionResponse(description='body', name='body') } /** * 下拉提示是搜索服务的基础功能,在用户输入查询词的过程中,智能推荐候选query,减少用户输入,帮助用户尽快找到想要的内容。 */ async function suggestEx(appName: string, modelName: string, request: SuggestRequestModel, runtime: Util.RuntimeOptions): SuggestResponseModel { return _request('GET', `/v3/openapi/apps/${appName}/suggest/${modelName}/search`, request.query, request.headers, null, runtime); } /** * 下拉提示是搜索服务的基础功能,在用户输入查询词的过程中,智能推荐候选query,减少用户输入,帮助用户尽快找到想要的内容。 */ async function suggest(appName: string, modelName: string, request: SuggestRequestModel): SuggestResponseModel { var runtime = new Util.RuntimeOptions{ connectTimeout = 5000, readTimeout = 10000, autoretry = false, ignoreSSL = false, maxIdleConns = 50, }; return suggestEx(appName, modelName, request, runtime); } model PushDocumentRequestModel { headers?: map[string]string(description='headers', name='headers'), body: [ Document ](description='body', name='body') } model PushDocumentResponseModel { headers?: map[string]string(description='headers', name='headers'), body: Response(description='body', name='body') } /** * 支持新增、更新、删除 等操作,以及对应批量操作 */ async function pushDocumentEx(appName: string, tableName: string, request: PushDocumentRequestModel, runtime: Util.RuntimeOptions): PushDocumentResponseModel { return _request('POST', `/v3/openapi/apps/${appName}/${tableName}/actions/bulk`, null, request.headers, request.body, runtime); } /** * 支持新增、更新、删除 等操作,以及对应批量操作 */ async function pushDocument(appName: string, tableName: string, request: PushDocumentRequestModel): PushDocumentResponseModel { var runtime = new Util.RuntimeOptions{ connectTimeout = 5000, readTimeout = 10000, autoretry = false, ignoreSSL = false, maxIdleConns = 50, }; return pushDocumentEx(appName, tableName, request, runtime); } model CollectDataRequestModel { headers?: map[string]string(description='headers', name='headers'), body: [ Behavior ](description='body', name='body') } model CollectDataResponseModel { headers?: map[string]string(description='headers', name='headers'), body: Response(description='body', name='body') } /** * 为了给客户提供更高质量的搜索效果,opensearch目前支持客户通过server端上传点击数据。 */ async function collectDataEx(appName: string, collectorName: string, request: CollectDataRequestModel, runtime: Util.RuntimeOptions): CollectDataResponseModel { return _request('POST', `/v3/openapi/app-groups/${appName}/data-collections/${collectorName}/actions/bulk`, null, request.headers, request.body, runtime); } /** * 为了给客户提供更高质量的搜索效果,opensearch目前支持客户通过server端上传点击数据。 */ async function collectData(appName: string, collectorName: string, request: CollectDataRequestModel): CollectDataResponseModel { var runtime = new Util.RuntimeOptions{ connectTimeout = 5000, readTimeout = 10000, autoretry = false, ignoreSSL = false, maxIdleConns = 50, }; return collectDataEx(appName, collectorName, request, runtime); } /** * */ model SearchResponse { status?: string(name='status'), requestId?: string(name='request_id'), result?: SearchResult(name='result'), errors?: [ Error ](name='errors'), } /** * 实际返回结果,包括查询耗时searchtime、引擎总结果数total、本次请求返回结果数num、本次查询最大返回结果数viewtotal、查询结果items、统计结果facet等信息 */ model SearchResult { searchtime?: double(name='searchtime', description='指引擎耗时,单位为秒。'), total?: integer(name='total', description='total为一次查询(不考虑config子句)引擎中符合条件的结果数(在结果数较多情况下,该值会做优化),一般用来做展示。'), viewtotal?: integer(name='viewtotal', description='考虑到性能及相关性,引擎最多会返回viewtotal个结果。如果需要翻页的话,要求start+hit必需要小于viewtotal'), num?: integer(name='num', description='num为本次查询请求(受限于config子句的start及hit)实际返回的条目,不会超过hit值。'), items?: [ object ](name='items', description='包含查询召回数据信息,其中fields为搜索召回内容。'), facet?: [ SearchResultFacet ](name='facet', description='用于存放Aggregate子句返回的信息。'), } /** * */ model SearchResultItemFullJson { fields?: map[string]any(name='fields', description='搜索召回内容'), variableValue?: map[string]any(name='variableValue', description='表示自定义参数返回结果,如获取distance距离值,variableValue 节点只有在config子句的format为xml或者fulljson时才能展现出来,json格式默认不展示。'), sortExprValues?: [ number ](name='sortExprValues', description='表示对应文档排序分。'), } /** * */ model SearchResultFacet { key?: string(name='key'), items?: [ { value?: string(name='value'), count?: integer(name='count'), } ](name='items'), } /** * */ model Error { code?: integer(name='code', description='错误代码'), message?: string(name='message', description='错误描述'), } /** * */ model Document { cmd: string(name='cmd', description='必选字段。定义该文档的操作行为,可以为“add”、“update”、“delete”,标准版不支持“update”。建议一个请求中进行批量更新操作,提高网络交互及处理效率。“add”表示新增文档,如果该主键对应文档已经存在,则执行先“delete”再“add”的操作;“update”表示更新文档,对该主键对应文档进行部分字段更新;“delete”表示删除文档,如果该主键对应文档已经不存在,则认为删除成功。', enum='add, update, delete'), timestamp?: integer(name='timestamp', description='可选字段。用来记录文档实际发生时间,单位为毫秒。系统会用该时间戳来作为同一主键文档更新顺序的判断标准,该选项仅支持高级版,标准版应用,没有该timestamp选项,若指定该选项,推送会报4007错误码。在没有该timestamp项时,默认以文档发送到OpenSearch的时间作为文档更新时间进行操作。'), fields: map[string]any(name='fields', description='必选字段。要操作的文档内容,主键字段必选,系统所有操作都是通过主键来进行的。对于“delete”只需要提供文档主键即可。'), } /** * */ model Behavior { cmd: string(name='cmd', description='必选字段。定义该文档的操作行为,目前仅支持ADD', enum='ADD'), fields: map[string]any(name='fields', description='必选字段。行为数据主体。'), } /** * object_id=pk,object_type=ops_search_doc,ops_request_misc=xxx */ model Event2001Args { objectId?: string(name='object_id', description='被点击的对象的主键,不能为空,如果通过api上传需要urlencode'), objectType?: string(name='object_type', description='必须为ops_search_doc', default='ops_search_doc'), opsRequestMisc?: string(name='ops_request_misc', description='开放搜索在搜索结果中返回的参数,只要原样设置即可。'), } /** * */ model SuggestionResponse { requestId?: string(name='request_id'), searchtime?: double(name='searchtime', description='引擎查询耗时,单位为秒'), suggestions?: [ { suggestion?: string(name='suggestion'), } ](name='suggestions'), errors?: [ Error ](name='errors'), } /** * */ model Response { status?: string(name='status'), requestId?: string(name='request_id'), errors?: [ Error ](name='errors'), } api _request(method: string, pathname: string, query: map[string]any, headers: map[string]string, body: any, runtime: Util.RuntimeOptions): map[string]any { var accesskeyId = getAccessKeyId(); var accessKeySecret = getAccessKeySecret(); __request.protocol = Util.defaultString(@protocol, 'HTTP'); __request.method = method; __request.pathname = pathname; __request.headers = { user-agent = getUserAgent(), Date = OpenSearchUtil.getDate(), host = Util.defaultString(@endpoint, `opensearch-cn-hangzhou.aliyuncs.com`), X-Opensearch-Nonce = Util.getNonce(), ...headers }; if (!Util.isUnset(query)) { __request.query = Util.stringifyMapValue(query); } if (!Util.isUnset(body)) { var reqBody = Util.toJSONString(body); __request.headers.Content-MD5 = OpenSearchUtil.getContentMD5(reqBody); __request.headers.Content-Type = 'application/json'; __request.body = reqBody; } __request.headers.Authorization = OpenSearchUtil.getSignature(__request, accesskeyId, accessKeySecret); } returns { var objStr = Util.readAsString(__response.body); if (Util.is4xx(__response.statusCode) || Util.is5xx(__response.statusCode)) { throw { message = __response.statusMessage, data = objStr, code = __response.statusCode }; } var obj = Util.parseJSON(objStr); var res = Util.assertAsMap(obj); return { body = res, headers = __response.headers }; } runtime { timeouted = 'retry', readTimeout = runtime.readTimeout, connectTimeout = runtime.connectTimeout, httpProxy = runtime.httpProxy, httpsProxy = runtime.httpsProxy, noProxy = runtime.noProxy, maxIdleConns = runtime.maxIdleConns, retry = { retryable = runtime.autoretry, maxAttempts = Util.defaultNumber(runtime.maxAttempts, 3) }, backoff = { policy = Util.defaultString(runtime.backoffPolicy, 'no'), period = Util.defaultNumber(runtime.backoffPeriod, 1) }, ignoreSSL = runtime.ignoreSSL } function setUserAgent(userAgent: string): void { @userAgent = userAgent; } function appendUserAgent(userAgent: string): void { @userAgent = `${@userAgent} ${userAgent}`; } function getUserAgent(): string { var userAgent = Util.getUserAgent(@userAgent); return userAgent; } async function getAccessKeyId(): string { if (Util.isUnset(@credential)) { return ''; } var accessKeyId = @credential.getAccessKeyId(); return accessKeyId; } async function getAccessKeySecret(): string { if (Util.isUnset(@credential)) { return ''; } var secret = @credential.getAccessKeySecret(); return secret; }