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, как указано в опциях.
Полный список параметров, которые можно настроить для управления поиском, см. В приложении "Справочник по параметрам запроса".