Проблема с cts: field-word-query - PullRequest
0 голосов
/ 25 мая 2018

Я создал поле с именем 'publishing-title' в моей базе данных MarkLogic (скажем, ABC) на основе элемента XPath.

Следующий запрос отлично работает на QC с источником контента в качестве базы данных 'ABC' (вкакое поле существует)

let $text := 'The Point'

let $query := cts:field-word-query("publication-titles", $text, 
("punctuation-sensitive", "case-insensitive", "whitespace-sensitive"), 5.0)

return
  xdmp:invoke-function(function()
    {
      cts:search(/Publication, $query)[1]
    },
    <options xmlns="xdmp:eval">
      <database>{xdmp:database("ABC")}</database>
    </options>
  )

Однако, если я изменю Источник контента на любую другую базу данных, я получаю следующую ошибку

[1.0-ml] XDMP-NOFIELD: cts:search(fn:collection()/Publication, cts:field-    
word-query("publication-titles", "The Point", ("case- 
insensitive","punctuation-sensitive","whitespace-sensitive","lang=en"), 5)) - 
- Field not defined: publication-titles
Stack Trace
At line 8 column 8:
In function() as item()*()

6. xdmp:invoke-function(function()
7. {
8. cts:search(/Publication, $query)[1]
9. },
10. <options xmlns="xdmp:eval">

Может кто-нибудь помочь мне понять, что здесь происходит не так?

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Некоторые конструкторы запросов имеют зависимости от контекста выполнения.Полевые запросы и запросы диапазона или геопространственных данных имеют наиболее очевидную зависимость (существует ли индекс? Каковы его параметры?), Но запросы значений и слов также проверяют конфигурацию, чтобы определить, являются ли они чувствительными к положению или включены вообще.Когда вы помещаете конструктор вне invoke-функции, он будет вызываться во внешней конфигурации.Часто это не будет иметь существенных различий, но во многих случаях это будет, или это будет иметь незначительное значение (например, не использовать позиции, когда вы должны были).Невозможно заставить эту работу работать так, как вам хотелось бы, так же как мы не могли бы сделать вызов xdmp:database(), работающий в этом контексте.

Все должно работать, если вы просто выполняете тот же вызов внутритело функции (т. е. просто поместите туда то же самое let / return).Ошибка в том, что это тоже не работает, потому что конструкторы неправильно думают, что они могут быть оптимизированы таким образом, что внешний контекст выполняет их на этапе оптимизации.Я исправлю это под 50017.

0 голосов
/ 25 мая 2018

(замененный ответ)

Похоже, вы столкнулись с неудачной ошибкой, которая, похоже, применима ко всем cts:field-*-query конструкторам запросов, но не ко всем остальным (не проверено полностью).

Встроенные функции испытывают трудности, связанные с контекстом, из которого они вызываются, а также со своими собственными, что объясняет потенциальные ссылки на неправильную базу данных.Это может быть сложно применить к правильному контексту.Я подал отчет об ошибке, так что, надеюсь, это скоро будет решено в одном из следующих выпусков патча.

Тем временем, лучше всего принудительно заставить конструктор запросов переоцениваться во внутреннем контексте.Это можно сделать, сериализовав запрос в XML и проанализировав его внутри встроенной функции.Это довольно легко сделать.Оберните конструктор document { .. }/*, и для его анализа вы используете cts:query($query):

let $text := 'The Point'

let $query := document{
  cts:field-word-query("publication-titles", $text, 
("punctuation-sensitive", "case-insensitive", "whitespace-sensitive"), 5.0)
}/*

return
  xdmp:invoke-function(function()
    {
      cts:search(/Publication, cts:query($query))[1]
    },
    <options xmlns="xdmp:eval">
      <database>{xdmp:database("ABC")}</database>
    </options>
  )

Сериализация и синтаксический анализ очень малы, но, вероятно, незначительны по сравнению с фактическим временем поиска..

HTH!

...