MarkLogic 9 cts.parse неправильно анализирует запросы

Я работаю над поисковым веб-приложением, использующим MarkLogic 9. У меня есть интерфейс построения запросов, который позволяет пользователям вводить строки в текстовые поля, которые соответствуют определенным свойствам JSON документов в БД. Идея заключалась в том, что пользователь мог вводить условия поиска в точности так, как их ожидает cts.parse (я использую javascript на стороне сервера, а не XQuery), поэтому их поиск может быть сколь угодно сложным, и мне не придется самостоятельно разбирать запросы., Однако после некоторого тестирования я обнаружил странное явление, касающееся использования скобок в булевой логике. А именно, когда вы включаете круглые скобки с такими утверждениями, как cat и (dog OR bird), cts.parse будет ошибочно принимать OR за поисковый запрос.

Я приведу пример с моего сайта:

Я создал объект привязки, чтобы связать запросы с элементами моих документов,

var qOpts = ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded"];


var bindings = {
 main: function(operator, values, options){
  return(
    cts.orQuery([
     cts.jsonPropertyWordQuery('title',values,qOpts),
     cts.jsonPropertyWordQuery('abstract',values,qOpts),
     cts.jsonPropertyWordQuery('meshterms',values,qOpts),
     ])
  );
 }, 
}

Мои серверные скрипты вызывают, например,

cts.parse('main:'+params.mainQuery,bind)

Вот несколько примеров введенных строк и возвращенных запросов:

  1. мозг или сердце или легкое

cts.orQuery([cts.jsonPropertyWordQuery("title", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("abstract", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("meshterms", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.wordQuery("heart", ["lang=en"], 1), cts.wordQuery("lung", ["lang=en"], 1)], [])

Он правильно генерирует jsonPropertyWordQuery для 3 полей (заголовок, аннотация, термины сетки) для термина "мозг", но не делает этого для двух других терминов, для которых он просто генерирует cts.wordQuery().

  1. мозг или сердце и легкое

cts.orQuery([cts.jsonPropertyWordQuery("title", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("abstract", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("meshterms", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.andQuery([cts.wordQuery("heart", ["lang=en"], 1), cts.wordQuery("lung", ["lang=en"], 1)], ["unordered"])], [])

  1. мозг или (сердце и легкие)

cts.orQuery([cts.jsonPropertyWordQuery("title", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("abstract", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("meshterms", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.andQuery([cts.wordQuery("heart", ["lang=en"], 1), cts.wordQuery("lung", ["lang=en"], 1)], ["unordered"])], [])

2 и 3 выглядят одинаково. Первая правильная часть генерирует jsonPropertyWordQuery, но другие термины добавляются в виде базовых запросов к словам, которых я пытаюсь избежать.

  1. (мозг или сердце) и легкие

cts.andQuery([cts.orQuery([cts.jsonPropertyWordQuery("title", ["brain", "OR", "heart"], ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("abstract", ["brain", "OR", "heart"], ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("meshterms", ["brain", "OR", "heart"], ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1)], []), cts.wordQuery("lung", ["lang=en"], 1)

Здесь парсер, похоже, не распознает, что OR является оператором, потому что, хотя он правильно генерирует jsonPropertyWordQueries, он включает OR в качестве термина в поиске.

Честно говоря, у меня возникают проблемы с поиском правильного запроса, что приводит меня к мысли, что я, должно быть, делаю что-то не так. Я понятия не имею, где это может быть. Я неправильно использую cts.parse или объект bindings?

Любая помощь будет принята с благодарностью.

2 ответа

Решение

Мне не ясно, какая у вас точная строка запроса.

Если строка запроса что-то вроде "main:(cat OR dog)" тогда OR не является ключевым словом в этом контексте. То, что разрешено после тега, довольно ограничено, и это не полный диапазон языка запросов, это просто список литералов.

Если строка запроса что-то вроде "main:cat OR dog тогда область применения тега cat,

Желательно, чтобы () после тега охватывал весь запрос, теперь вы можете привязать функцию к тегу (это не имело смысла, когда она была зафиксирована в индексе диапазона или поле), но это не так грамматика настроена.

Так что вам просто нужно делать что-то по частям: main:cat OR main:dog

Или: учитывая набор значений, переданных в вашу функцию, соедините их пробелами и передайте их отдельному вызову cts:parse чтобы получить их интерпретировать как запрос, который вы можете обернуть.

Как также объясняет Мария, вы должны прочитать main:cat OR dog как (main:cat) OR dog, Вы можете сделать что-то, как предлагает Эрик, и переписать запрос, прежде чем анализировать main:cat OR main:dogили вы могли бы разобрать cat OR dog (без префикса), а затем постобработать дерево запросов cts: для расширения вхождений cts:word-query с тремя или несколькими запросами, которые вы ищете. Рекурсивная функция, использующая переключатель типов, должна добиться цели.

НТН!

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