marklogic - 如何在查询控制台的上下文中运行 MarkLogic RestAPI 调用?
问题描述
我想分析对自定义函数的 RestAPI 调用。看来我有几个选择。请评论每一个:
- 从给定应用程序服务器端口的访问日志或请求日志中提取 RestAPI 调用并将其复制到查询控制台。我不知道这是否可能,除非我使用
xdmp:http-post
orxdmp.httpPost
API 调用来调用 RestAPI 调用。我只是不确定配置一个 Rest 调用是否有意义。 - 我有一个自定义的“zsearch”模块/库来处理搜索请求并压缩结果。我想我可以将
return:plan
andreturn:metrics
选项添加到函数中搜索查询的参数中zsearch:get()
,但我不明白在下面的代码示例中这样做的语法,我想硬编码返回调用。有人可以提供一个例子吗?
此外,此模块利用/MarkLogic/rest-api/models/search-model-query.xqy处的 search-model-query Rest API 调用。我想知道这个模块的位置,因为我想查看它并向它添加一些日志记录。我不确定为什么代码使用search-model-query.xqy
库而不是search:search
调用。似乎该search:search
调用将比从数据库模块内进行的后续 Rest API 调用更有效。
我还想了解将此代码从使用search-model-query.xqy 移植到https://docs.marklogic.com/search:searchsearch:search
中描述的功能需要什么。
这是zsearch代码:
module namespace zsearch = "http://marklogic.com/rest-api/resource/zsearch";
import module namespace lid = "http://marklogic.com/util/log-id"
at "/MarkLogic/appservices/utils/log-id.xqy";
import module namespace searchmodq = "http://marklogic.com/rest-api/models/search-model-query"
at "/MarkLogic/rest-api/models/search-model-query.xqy";
import module namespace sut = "http://marklogic.com/rest-api/lib/search-util"
at "/MarkLogic/rest-api/lib/search-util.xqy";
import module namespace eput = "http://marklogic.com/rest-api/lib/endpoint-util"
at "/MarkLogic/rest-api/lib/endpoint-util.xqy";
declare default function namespace "http://www.w3.org/2005/xpath-functions";
declare option xdmp:mapping "false";
(:
declare option xdmp:transaction-mode "auto";
:)
declare private function zsearch:response-callback(
$response-type as xs:string?
) as empty-sequence()
{
eput:response-type-callback($response-type),
let $timestamp := xdmp:request-timestamp()
return if (exists($timestamp)) then eput:add-response-header("ML-Effective-Timestamp",string($timestamp)) else ()
};
declare private function zsearch:query-parameter(
$paramMap as map:map,
$params as map:map,
$name as xs:string,
$required as xs:boolean,
$repeatable as xs:boolean,
$allowed as xs:string*,
$privileges as xs:string*,
$converter as function(*)?
) as map:map
{
let $values := map:get($params,$name)
return (
if (not($required) or exists($values[. ne ""])) then ()
else error((),"REST-REQUIREDPARAM",$name),
if (empty($values))
then $paramMap
else (
if (empty($privileges) or xdmp:has-privilege($privileges, "execute")) then ()
else error((),"REST-INVALIDPARAM", concat(
$name," parameter requires at least one privilege: ",string-join($privileges,", ")
)),
if ($repeatable or count($values) lt 2) then ()
else error((),"REST-REPEATEDPARAM",$name),
map:with($paramMap,$name,
if (empty($allowed) and empty($converter))
then $values
else
let $fname :=
if (empty($converter)) then ()
else function-name($converter)
let $fns :=
if (empty($fname)) then ()
else namespace-uri-from-QName($fname)
let $flocal :=
if (not($fns = ("http://www.w3.org/2001/XMLSchema"))) then ()
else local-name-from-QName($fname)
for $val in $values
let $converted :=
if (empty($converter))
then $val
else if (empty($flocal) or xdmp:castable-as($fns,$flocal,$val))
then $converter($val)
else error((),"REST-INVALIDPARAM", concat(
$name, " parameter not convertible to xs:",
local-name-from-QName($fname)," value: ",string($val)
))
return
if (exists($allowed) and not($converted = $allowed))
then error((),"REST-INVALIDTYPE",
($name, $val, "is not one of", string-join($allowed, "|")))
else $converted
)
)
)
};
declare private function zsearch:validate-parameter-names(
$paramMap as map:map,
$params as map:map,
$ignore-patterns as xs:string*
) as xs:string*
{
for $name in map:keys($params)
return
if (map:contains($paramMap,$name)) then ()
else zsearch:check-ignore($name,$ignore-patterns)
};
declare private function zsearch:check-ignore(
$name as xs:string,
$ignore-patterns as xs:string*
) as xs:string?
{
if (exists($ignore-patterns) and exists(
for $pattern in $ignore-patterns
return
if (matches($name,$pattern))
then true()
else ()
))
then ()
else $name
};
declare private function zsearch:compress(
$data as document-node()*
) as document-node()
{
let $zip := xdmp:zip-create(
<parts xmlns="xdmp:zip"><part>result.json</part></parts>,
($data)
)
return document { $zip }
};
declare function zsearch:get($context as map:map, $params as map:map) as document-node()* {
let $headers := eput:get-request-headers()
let $accept := eput:get-accept-types($headers)
let $method := eput:get-request-method($headers)
let $env := eput:response-callback-map(zsearch:response-callback#1)
let $paramMap := map:new()
=>zsearch:query-parameter($params,"q",false(),false(),(),(),())
=>zsearch:query-parameter($params,"category",false(),true(),("content","metadata","collections","permissions","properties","quality","metadata-values"),(),())
=>zsearch:query-parameter($params,"format",false(),false(),("json","xml"),(),())
=>zsearch:query-parameter($params,"start",false(),false(),(),(),xs:unsignedLong#1)
=>zsearch:query-parameter($params,"pageLength",false(),false(),(),(),xs:unsignedLong#1)
=>zsearch:query-parameter($params,"options",false(),false(),(),(),())
=>zsearch:query-parameter($params,"collection",false(),true(),(),(),())
=>zsearch:query-parameter($params,"directory",false(),false(),(),(),())
=>zsearch:query-parameter($params,"view",false(),true(),("none","results","metadata","facets","all"),(),())
=>zsearch:query-parameter($params,"txid",false(),false(),(),(),())
=>zsearch:query-parameter($params,"database",false(),false(),(),(),())
=>zsearch:query-parameter($params,"forest-name",false(),true(),(),(),())
=>zsearch:query-parameter($params,"transform",false(),false(),(),(),())
=>zsearch:query-parameter($params,"timestamp",false(),false(),(),(),())
=>zsearch:query-parameter($params,"trace",false(),true(),(),"http://marklogic.com/xdmp/privileges/rest-tracer",())
let $extra-names := zsearch:validate-parameter-names(
if ($method = ("GET", "HEAD"))
then zsearch:query-parameter($paramMap,$params,"structuredQuery",false(),false(),(),(),())
else $paramMap,
$params,
('name')
)
return (
if (empty($extra-names)) then ()
else error((),"REST-UNSUPPORTEDPARAM", concat(
"invalid parameters: ",string-join($extra-names,", ")
)),
lid:enable(map:get($paramMap,"trace")),
if (searchmodq:check-untraced()) then ()
else lid:log(
$searchmodq:trace-id,"zearch",
map:entry("method",$method)=> map:with("headers",$headers)=> map:with("parameters",$paramMap)
),
if (empty($accept)) then ()
else if ($accept = ("application/json", "text/json", "application/xml", "text/xml")) then
if (map:contains($paramMap,"category"))
then error((),"REST-UNSUPPORTEDPARAM",
"Can use the 'category' parameter only with multipart/mixed accept")
else
let $view := map:get($paramMap,"view")
return
if (not($view eq "none")) then ()
else error((),"REST-UNSUPPORTEDPARAM",
"Can use the 'none' value for the 'view' parameter only with multipart/mixed accept")
else if (starts-with(head($accept),"multipart/mixed"))
then map:put($env,"add-header",eput:add-response-header#2)
else error((), "REST-UNACCEPTABLETYPE", string-join($accept,", ")),
let $_ := 1
return (
let $response := searchmodq:search-get($headers,$paramMap,$env)
let $has-matches := map:get($env, "has-matches")
return
if (exists($response)) then
(:
let $_ := map:put($context,"output-type","application/octet-stream")
:)
let $_ := xdmp:set-response-content-type("application/octet-stream")
return zsearch:compress($response)
else if ($has-matches) then ()
else xdmp:set-response-code(404,"Not Found")
)
)
};```
解决方案
您可以使用xdmp:http-get()
或xdmp:http-post()
点击实际端点并通过 HTTP 使用适当的操作调用它。您可以在选项中指定return-plan
and :return-metrics
xdmp:http-get("http://localhost:8000/LATEST/config/resources/zsearch",
<options xmlns="xdmp:http">
<authentication method="basic">
<username>myname</username>
<password>mypassword</password>
<return-metrics>true</return-metrics>
<return-plan>true</return-plan>
</authentication>
</options>)
您还可以导入已安装的 REST 模块并以编程方式调用它的方法,而不是通过 HTTP 端点:
import module namespace zsearch = "http://marklogic.com/rest-api/resource/zsearch"
at "/marklogic.rest.resource/zsearch/assets/resource.xqy";
let $context as map:map := map:new()
let $params as map:map := map:new()
return
zsearch:get($context, $params)
你也可以使用xdmp:plan()
和xdmp:query-meters()
该模块/MarkLogic/rest-api/models/search-model-query.xqy
可以在任何 MarkLogic 服务器的 MarkLogic 安装中找到。它位于安装位置下/Modules/MarkLogic/rest-api/models/search-model-query.xqy
。
推荐阅读
- python - 优化 dask.distributed 调度以减少数据
- mysql - 如何在优先查询中使用 OR?
- asterisk - PJSIP:为什么我可以拨打电话但在 Asterisk 16 控制台中记录为不可用?
- javascript - 在多个循环中组合单独的数组?
- python - 如何评估给定矩阵的 SymPy PurePoly?
- javascript - 粘性侧边栏不是那么粘
- c++ - 在c ++中打开文件,删除标点符号并附加到另一个文件中
- azure-active-directory - Azure AD B2C 自定义策略自定义错误页面未显示
- javascript - 如何从输入中删除“,”
- python - ROS 的 pydev 模块导入与控制台