MarkLogic - 自定义搜索代码段

时间:2017-02-17 19:55:13

标签: xquery marklogic marklogic-8 roxy

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

我正在尝试提交searchTerm,并返回自定义格式search:snippet

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

./../roxy/ml new test-app --server-version=8 --app-type=rest

配置我的build.properties

cd test-app/ ./ml local bootstrap

现在我有了项目结构。

创建文件 - test-app / rest-api / 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" }
};

上面的GET请求使用transform-results apply=raw选项,正确部署和运行(我有一些测试文档)。

但是我不想返回整个文档,我想返回一个匹配的json的整个部分,无论在哪个区域匹配发生(较低级别)

所以我尝试编写自己的snipper

创建文件 - test-app / rest-api / ext / show-search-snipper.xqy

xquery version "1.0-ml";

module namespace sss = "http://marklogic.com/rest-api/resource/show-search-snipper";
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 sss:my-snippet(
    $result as node(),
    $ctsquery as schema-element(cts:query),
    $options as element(search:transform-results)?
) as element(search:snippet)
{
    <search:snippet>

    </search:snippet>
};

然后我将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>
      )

现在我应该拥有我需要的一切(我认为)

我运行部署./ml local deploy rest

并获得以下

  

Minty-linux test-app#。/ ml local deploy rest加载REST属性   在/opt/this-is-a-test/test-app/rest-api/config/properties.xml中加载   / opt / this-is-a-test / test-app / rest-api / config / options中的REST选项

     

从/ opt / this-is-a-test / test-app / rest-api / ext

加载REST扩展      

错误:400&#34;错误请求&#34;错误:{&#34; errorResponse&#34;:{&#34; statusCode&#34;:400,   &#34; status&#34;:&#34; Bad Request&#34;,&#34; messageCode&#34;:&#34; RESTAPI-INVALIDCONTENT&#34;,   &#34; message&#34;:&#34; RESTAPI-INVALIDCONTENT :(错误:FOER0000)内容无效:   无效的show-search-snipper扩展:show-search-snipper也是   不是有效的模块或不提供扩展功能(删除,   获取,放置,发布)   http://marklogic.com/rest-api/resource/show-search-snipper   命名空间&#34;}}

所以我尝试将show-search-snipper.xqy文件向上移动1级(到test-app / rest-api / show-search-snipper.xqy`

运行部署 部署工作没有错误 点击URL并收到以下

  

  500内部服务器错误   内部错误   RESTAPI-INVALIDREQ :(错误:FOER0000)无效请求:原因:扩展   show-search不存在。 。请参阅MarkLogic服务器错误日志   更多细节。

虽然我知道扩展是正确创建的,因为它在引入自定义剪辑功能之前工作正常。 (使用apply =&#34; raw&#34;)

有什么想法我可以如何应用我的自定义剪辑功能或我在部署中做错了什么?

enter image description here

2 个答案:

答案 0 :(得分:1)

您是否决定坚持使用自定义代码段:

看起来Roxy正试图将它作为资源扩展程序对待你的snippeter模块,但事实并非如此。你的snippeter应该只是db。模块中的一个vanilla模块。

IDK如何配置Roxy,遗憾的是,你的目标是让Roxy在你的模块db上使用PUT /v1/ext/directories/asset或直接插入('PUT / v1 / documents)来安装它。请参阅http://docs.marklogic.com/REST/PUT/v1/ext/[directories]/[asset]

假设Roxy使用/ ext,那么你的snippeter的路径将不是你选择中的不合格路径。它将是一个以/ ext /为根的绝对路径。请参阅http://docs.marklogic.com/guide/rest-dev/search#id_72390

答案 1 :(得分:0)

有一种更简单的方法 - 您可以使用extract-document-data搜索选项执行此操作。

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

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 } }')
  )

通过引导和部署模块,我可以在http://localhost:8040/v1/search获得搜索结果。但是,我可以通过使用存储的搜索选项开始更多地控制搜索结果。在rest-api/config/options/all.xml查看您的项目。当您运行ml local deploy modules时,系统已经为您部署了它们,因此您现在可以使用http://localhost:8040/v1/search?options=all进行搜索。由于您正在使用JSON数据,因此我更进了一步,并使用:http://localhost:8040/v1/search?format=json&options=all运行。

我将此添加到rest-api/config/options/all.xml

<extract-document-data selected="include">
  <extract-path>/important</extract-path>
</extract-document-data>

这告诉搜索选项在所有搜索结果中包含指定的路径。再次部署并运行搜索后,一个结果如下所示:

{
  "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}}
    ]
  }
}, 

注意那里的“提取”部分 - 我得到了“重要的”JSON属性,如选项中所指定的那样。

有关您可以设置为控制搜索的完整选项列表,请参阅Query Options Reference appendix