MarkLogic - Фрагмент пользовательского поиска

Я использую 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 option, развертывается и функционирует должным образом (у меня есть несколько тестовых документов).

Однако я не хочу возвращать весь документ, я хочу вернуть целый раздел 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 Загрузка параметров REST в / opt / this- это-тест / тест-приложение / отдых-API / Config / опции

Загрузка расширений REST из / opt / this-is-a-test / test-app / rest-api / ext

ОШИБКА: 400 "Неверный запрос" ОШИБКА: {"errorResponse":{"statusCode":400, "status":"Неверный запрос", "messageCode":"RESTAPI-INVALIDCONTENT", "message":"RESTAPI-INVALIDCONTENT: (ошибка:FOER0000) Недопустимое содержимое: недопустимое расширение show-search-snipper: show-search-snipper либо не является допустимым модулем, либо не предоставляет функций расширения (удаление, получение, помещение, публикация) на http://marklogic.com/rest-api/resource/show-search-snipper namespace "}}

Поэтому я попытался переместить show-search-snipper.xqy файл на 1 уровень (в test-app/rest-api/show-search-snipper.xqy`

Запустите развертывание. Развертывание работает. Нет ошибок. Нажмите URL и получите следующее.

500 Внутренняя ошибка сервера ВНУТРЕННЯЯ ОШИБКА RESTAPI-INVALIDREQ: (ошибка:FOER0000) Недопустимый запрос: причина: расширение show-search не существует., См. Журнал ошибок сервера MarkLogic для получения дополнительной информации.

Хотя я знаю, что расширение было создано правильно, так как оно работало нормально до появления пользовательской функции отсечения. (с apply="raw")

Любые мысли о том, как я могу применить свою пользовательскую функцию снэпа или что я делаю неправильно при развертывании?


введите описание изображения здесь

2 ответа

Решение

Если вы решите придерживаться специального сниппера:

Похоже, что Roxy пытается рассматривать ваш модуль сниппера как расширение ресурса, а это не так. Ваш сниппер должен быть просто ванильным модулем в модулях БД.

IDK, как настроить Roxy, к сожалению, но вы хотите, чтобы Roxy либо установил его, используя PUT /v1/ext/directories/asset или прямая вставка (`PUT /v1/documents) в ваши модули db. См. http://docs.marklogic.com/REST/PUT/v1/ext/[directories]/[asset].

Предполагая, что Roxy использует / ext, тогда путь к вашему снипперу НЕ будет безусловным путем, который вы указали в ваших настройках. Это был бы абсолютный путь с корнем в / ext /. См. http://docs.marklogic.com/guide/rest-dev/search.

Есть более простой способ - вы можете сделать это с помощью опции поиска 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, как указано в опциях.

Полный список параметров, которые можно настроить для управления поиском, см. В приложении "Справочник по параметрам запроса".

Другие вопросы по тегам