Xquery MarkLogic-自定义搜索片段

Xquery MarkLogic-自定义搜索片段,xquery,marklogic,marklogic-8,roxy,Xquery,Marklogic,Marklogic 8,Roxy,我正在使用Roxy来管理我的项目。也使用MarkLogic 8.0-6.1 我试图提交一个searchTerm,并返回一个自定义格式的search:snippet 以下是我正在采取的完整步骤: /。/roxy/ml新测试应用程序--服务器版本=8--应用程序类型=rest 配置我的build.properties cd测试应用程序/ /ml本地引导 现在我有了我的项目结构 创建文件-test app/restapi/ext/show-search.xqy xquery version "1.0-

我正在使用Roxy来管理我的项目。也使用MarkLogic 8.0-6.1

我试图提交一个searchTerm,并返回一个自定义格式的
search:snippet

以下是我正在采取的完整步骤:

/。/roxy/ml新测试应用程序--服务器版本=8--应用程序类型=rest

配置我的build.properties

cd测试应用程序/
/ml本地引导

现在我有了我的项目结构

创建文件-test app/restapi/ext/show-search.xqy

xquery version "1.0-ml";

module namespace ss = "http://marklogic.com/rest-api/resource/show-search";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
import module namespace json = "http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";




declare
function ss:get(
  $context as map:map,
  $params  as map:map
) as document-node()*
{

  map:put($context, "output-types", "application/json"),
  map:put($context, "output-status", (200, "OK")),

  let $search-term := map:get($params, "searchTerm")
  let $query := search:search($search-term,
      <options xmlns="http://marklogic.com/appservices/search">
        <transform-results apply="raw"/>
      </options>
      )

  return document {$query} 
};

(:
 :)
declare 
function ss:put(   
    $context as map:map,
    $params  as map:map,
    $input   as document-node()*
) as document-node()?
{
  map:put($context, "output-types", "application/xml"),
  map:put($context, "output-status", (201, "Created")),
  document { "PUT called on the ext service extension" }
};

(:
 :)
declare 
function ss:post(
    $context as map:map,
    $params  as map:map,
    $input   as document-node()*
) as document-node()*
{
  map:put($context, "output-types", "application/xml"),
  map:put($context, "output-status", (201, "Created")),
  document { "POST called on the ext service extension" }
};

(:
 :)
declare 
function ss:delete(
    $context as map:map,
    $params  as map:map
) as document-node()?
{
  map:put($context, "output-types", "application/xml"),
  map:put($context, "output-status", (200, "OK")),
  document { "DELETE called on the ext service extension" }
};
然后,我将
search:search
调用更新为

  let $query := search:search($search-term,
      <options xmlns="http://marklogic.com/appservices/search">
        <transform-results apply="my-snippet" ns="http://marklogic.com/rest-api/resource/show-search-snipper" at="show-search-snipper.xqy"/>
      </options>
      )
let$query:=search:search($search-term,
)
现在我应该拥有我需要的一切(我想)

我运行deploy
/ml本地deploy rest

并获得以下信息

Minty linux测试应用程序#./ml本地部署rest加载rest属性 在/opt/this-is-a-test/test-app/restapi/config/properties.xml加载中 /opt/this-is-a-test/test-app/restapi/config/options中的REST选项

从/opt/this-is-a-test/test-app/restapi/ext加载REST扩展

错误:400“错误请求”错误:{“错误响应”:{“状态代码”:400, “状态”:“错误请求”,“消息代码”:“RESTAPI-INVALIDCONTENT”, “消息”:“RESTAPI-INVALIDCONTENT:(错误:FOER0000)无效内容: 无效的显示搜索snipper扩展:显示搜索snipper为 不是有效的模块或不提供扩展功能(删除, 把…放在…里 命名空间“}}

因此,我尝试将
show search snipper.xqy
文件上移1级(以测试app/restapi/show-search-snipper.xqy)`

运行部署 部署不会出错 点击URL并接收以下内容

  let $query := search:search($search-term,
      <options xmlns="http://marklogic.com/appservices/search">
        <transform-results apply="my-snippet" ns="http://marklogic.com/rest-api/resource/show-search-snipper" at="show-search-snipper.xqy"/>
      </options>
      )
500内部服务器错误 内部错误 RESTAPI-INVALIDREQ:(错误:FOER0000)无效请求:原因:扩展 显示搜索不存在..有关详细信息,请参阅MarkLogic服务器错误日志 进一步的细节

虽然我知道扩展创建得很好,但在引入自定义snip函数之前,它工作得很好

有什么想法我可以应用我的自定义剪贴功能,或者我在部署中做错了什么


有一种更简单的方法——您可以使用搜索选项来实现这一点

我设置了一些示例数据,如下所示:

xquery version "1.0-ml";

for $i in (1 to 10)
return 
  xdmp:document-insert(
    '/test-content-' || $i || '.json',
    xdmp:unquote('{ "important": { "foo": 1, "bar": 2 }, "not-important": { "stuff": 3, "blah": 4 } }')
  )
{
  "index":1, 
  "uri":"/test-content-6.json", 
  "path":"fn:doc(\"/test-content-6.json\")", 
  "score":0, 
  "confidence":0, 
  "fitness":0, 
  "href":"/v1/documents?uri=%2Ftest-content-6.json", 
  "mimetype":"application/json", 
  "format":"json", 
  "matches":[{"path":"fn:doc(\"/test-content-6.json\")/object-node()", "match-text":[]}], 
  "extracted":{
    "kind":"array", 
    "content":[
      {"important":{"foo":1, "bar":2}}
    ]
  }
}, 
有了引导和部署的模块,我可以在处获得搜索结果。但是,我可以通过使用存储的搜索选项开始对搜索结果进行更多控制。请查看您的项目,网址为
rest api/config/options/all.xml
。在运行
ml local deploy modules
时,它们已经为您部署好了,因此您现在可以因为您使用的是JSON数据,所以我更进一步,使用:

我将其添加到
restapi/config/options/all.xml

<extract-document-data selected="include">
  <extract-path>/important</extract-path>
</extract-document-data>
注意最后的“提取”部分——我得到了选项中指定的“重要”JSON属性


有关可设置为控制搜索的选项的完整列表,请参阅。

如果您决定继续使用自定义代码段:

看起来Roxy正试图将其作为您的代码段模块作为资源扩展来处理,但事实并非如此。您的代码段应该只是模块数据库中的普通模块

IDK如何配置Roxy,很遗憾,但您的目标是让Roxy使用
PUT/v1/ext/directories/asset
安装它,或者在模块数据库上直接插入(`PUT/v1/documents)。请参阅


假设Roxy使用/ext,那么代码段的路径将不是选项中的非限定路径。它将是根在/ext/的绝对路径。请参见。

Hi Dave,我实际上已经尝试过类似的方法,但我遇到的问题是,与您的
important
等效的实际上是一个数组,当我尝试此方法时,它是returns数组中的每个对象,而不仅仅是具有匹配项的项。我添加了一个显示1个匹配项的图片,并将多个段返回到OPokay,因此“重要”应该是一个对象数组,并且您希望仅从该数组中提取匹配的对象。例如,如果数组有多个对象,如{“源”:“随便”,“内容”:“再见,感谢所有的鱼”},搜索词为“鱼”,您希望获取该对象并返回它。对吗?为了完整起见,Kim是对的。如果您将xqy放在rest api/ext/文件夹中,Roxy会假定它是rest扩展。我建议将它放在
test app/src/search/show search snipper.xqy
中,然后将选项文件中的
at
属性更改为
>at=“/search/show search snipper.xqy”
。。