Путать с поиском: предложить - PullRequest
2 голосов
/ 01 сентября 2011

Я не могу предоставить эту простую функцию автозаполнения с помощью функции поиска: предложить.

Основываясь на корпусе Oscars из данных Marklogic Demo, я пытаюсь предоставить запрос на предложение, который был дляЭкземпляр может вернуть «Роберт Лоджия» в качестве ответа, даже если пользователь в данный момент пишет «Роберт Ло», «Лоджия Роб» или даже «Л Роб».

В настоящее время я могу только вернуться »Роберт Лоджия "среди своих коллег с таким простым запросом:

let $options := 
<options xmlns="http://marklogic.com/appservices/search">
  <default-suggestion-source>
    <range type="xs:string">
      <element ns="http://marklogic.com/wikipedia" name="name" />
    </range>
  </default-suggestion-source>
</options>
return search:suggest("Rob",$options)

Но как только я пишу фразу из двух слов, я не уверен, что пойму, как это написать, потому что никто изответ правильный с тем, что я жду.Например:

search:suggest("Robert Lo",$options)

или

search:suggest(("Robert", "Lo"),$options)

Это из-за отсутствия опции, неверной конфигурации индексов или неправильно используемой функции?

Спасибо за помощь

Ответы [ 3 ]

3 голосов
/ 09 сентября 2011

Это grammar-aware.

Вам нужно добавить кавычки вокруг фразы, если вы хотите получить предложения по фразе, в противном случае она обрабатывает токены отдельно.Попробуйте следующее:

search:suggest('"Robert Lo"',$options)
2 голосов
/ 09 сентября 2011

Это распространенная ошибка, я сам делал это несколько раз.

Как говорит Коллин, вам нужно поместить кавычки вокруг строки запроса. Это аналогично общему поиску с использованием API поиска или Google в этом отношении: с кавычками ваш аргумент считается фразой, а без каждого токена - отдельным аргументом.

Без кавычек поведение по умолчанию состоит в том, что два термина рассматриваются как отдельные токены, а также И или ИЛИ вместе в запросе, в зависимости от вашей конфигурации.

1 голос
/ 01 сентября 2011

Это тоже странно для меня, используя 4.2-6 на OS X. Вот как выглядели результаты в моем тесте с использованием полного набора данных оскаров.

import module namespace search = "http://marklogic.com/appservices/search"
    at "/MarkLogic/appservices/search/search.xqy";

let $options := 
<options xmlns="http://marklogic.com/appservices/search">
  <default-suggestion-source>
    <range type="xs:string">
      <element ns="http://marklogic.com/wikipedia" name="name" />
    </range>
  </default-suggestion-source>
</options>
return search:suggest("Robert Lo", $options)
=>
Robert "Loretta Young"
Robert "Lorraine Bracco"
Robert "Lotte Lenya"
Robert "Louis Calhern"
Robert "Louis Gossett, Jr."
Robert "Louis Malle"
Robert "Louise Fletcher"

Похоже, что значениягенерируется для or-query (('Robert', 'Lo')) и затем сливается нечетным образом.Если мы перейдем к использованию функции лексикона cts, все будет выглядеть нормально.

cts:element-value-match(
  QName('http://marklogic.com/wikipedia', 'name'),
  'Robert Lo*')
=>
Robert Loggia

Аспект подстановки слов усложняет ситуацию и выходит за рамки того, что обычно делает autosuggest (и что search:suggestи cts:element-value-match может обойтись без помощи).

Вот версия, в которой используются дополнительные операции со строками для создания двух шаблонов, обрабатывающих пары слов.Предполагается, что первое слово всегда завершено, в то время как второе может быть заглушкой, но слова могут потребоваться поменять местами для совпадения.Если вы определите желаемую логику, вы сможете изменить ее в соответствии с вашими требованиями.Обратите внимание, что отображение функции в игре, поэтому cts:element-value-match вызывается один раз для каждого шаблона во время оценки.Это может повлиять на производительность.

let $toks := cts:tokenize($INPUT)[. instance of cts:word]
let $pat := (
  if (count($toks) eq 1) then concat($toks, '*')
  else (
    concat($toks[2], '* ', $toks[1]),
    concat($toks[1], ' ', $toks[2], '*')))
return cts:element-value-match(
  QName('http://marklogic.com/wikipedia', 'name'),
  $pat)
=>
Robert Loggia
...