Как выполнить поиск по нескольким терминам внутри элемента

Я пытаюсь выполнить поиск, который проверяет, что каждое слово в строке запроса содержится в определенном элементе. Например, если $query = "Sports With Stripes", то конкретный элемент должен содержать все три слова (в любом порядке, так что это не словосочетание).

Чтобы ограничить поиск элементом, у меня есть следующее ограничение:

        <constraint name="inelement">
            <word>
                <element ns="" name="myElement"/>
                <term-option>case-insensitive</term-option>
            </word>
        </constraint>

Это кажется нормальным, но я борюсь, когда дело доходит до того, что нужно добавить в search:search. Я сначала попробовал это:

search:search('inelement:spots with stripes', $options, 1, 25)

Это не сработало, так как просто ограничивает "spots" моим элементом.

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

search:search('inelement:spots inelement:with inelement:stripes', $options, 1, 25)

Есть ли способ лучше? Или мне нужно вручную проанализировать мою строку запроса, чтобы разделить их на отдельные слова, прежде чем добавлять ограничение в мой search:search?


person Francium123    schedule 15.08.2013    source источник


Ответы (2)


Чтобы применить ограничение к пробелам, используйте кавычки.

inelement:"spots with stripes"

С помощью синтаксического анализатора по умолчанию, который вернет термин из одного слова-элемента. Чтобы разбить термин на слова, вы можете написать собственную функцию парсера. Пример можно найти по адресу http://docs.marklogic.com/guide/search-dev/search-api#id_49750

Вы можете захотеть, чтобы cts:near-query гарантировало, что все три слова находятся в одном и том же элементе. И вам может понадобиться включить element-word-positions в конфигурации базы данных.

person mblakele    schedule 15.08.2013

Вместо search:search вы можете использовать комбинацию search:parse и search:resolve и выполнять свою собственную обработку между ними. Если вы хотите всегда искать в определенном элементе, вы можете обновить запрос между этими шагами.

declare function local:word-to-element-query(
  $element as xs:QName,
  $query as item()
) as item()
{
  typeswitch ($query)
  case element(cts:word-query)
    return cts:element-word-query($element, 
      $query/cts:text/string(),
      $query/cts:option/string())
  case text() return $query
  default return 
    element { node-name($query) } {
      $query/@*, local:word-to-element-query($element, $query/node())
    }
};

let $query := 
  local:word-to-element-query(
    xs:QName('myElement'),
    search:parse('spots with stripes'))
return search:resolve($query)

Шаблон рекурсивного переключателя типов является хорошей стратегией для изменения выходных данных синтаксического анализа по умолчанию и добавления другой пользовательской логики.

person wst    schedule 15.08.2013