MarkLogic cts: элемент-запрос ложных срабатываний?


Учитывая этот документ : -

<items>
  <item><type>T1</type><value>V1</value></item>
  <item><type>T2</type><value>V2</value></item>
</items>

Неудивительно, что я нахожу, что это потянет назад страницу в a cts:uris() :-

cts:and-query((
  cts:element-query(xs:QName('item'),
    cts:element-value-query(xs:QName('type'),'T1')
    ),
  cts:element-query(xs:QName('item'),
    cts:element-value-query(xs:QName('value'),'V2')
    )
  ))
Но несколько неожиданно (по крайней мере для меня) я также нахожу, что это тоже будет: -
cts:element-query(xs:QName('item'),
  cts:and-query((
    cts:element-value-query(xs:QName('type'),'T1'),
    cts:element-value-query(xs:QName('value'),'V2')
    ))
  )

Это не кажется правильным, так как нет ни одного элемента с типом=T1 и значением=V2. Мне это кажется ложным позитивом.

Я неправильно понял, как работает cts:element-query? (Я должен сказать, что документация не особенно ясна в этом область).

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

2 6

2 ответа:

В дополнение к ответу @wst, вам нужно только включить element value positions, чтобы получить точные результаты от нефильтрованного поиска. Вот некоторый код, чтобы показать это:

xdmp:document-insert("/items.xml", <items>
  <item><type>T1</type><value>V1</value></item>
  <item><type>T2</type><value>V2</value></item>
</items>);

cts:search(collection(),
  cts:element-query(xs:QName('item'),
    cts:and-query((
      cts:element-value-query(xs:QName('type'),'T1'),
      cts:element-value-query(xs:QName('value'),'V2')
    ))
  ), 'unfiltered'
)

Без element value positions включено возвращает тестовый документ. После включения позиций запрос ничего не возвращает.

Как сказал @wst, cts:search() выполняется фильтрованным по умолчанию, тогда как cts:uris() (и, например, xdmp:estimate() работает только без фильтра.

ХТ!

Да, я думаю, что это небольшое недопонимание того, как работают запросы. В cts:search по умолчанию используется параметр filtered. В этом случае ML будет оценивать запрос, используя только индексы, а затем, как только документы-кандидаты будут выбраны, он загрузит их в память, проверит и отфильтрует ложные срабатывания. Это более трудоемко, но зато более точно.

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

Самый простой способ обработки этого запроса с помощью индексов-изменить схему таким образом, чтобы документы основывались на <item>, а не на <items>. Тогда каждый элемент будет иметь отдельную запись индекса, и результаты не будут смешиваться перед фильтрацией.

Еще один способ, который не требует обновления документов, - это обернуть запросы, которые вы ожидаете встретить в том же элементе, в cts:near-query. Это помешало бы a <type> в одном <item> совпадать с A <value> в a разные <item>. Я предлагаю прочитать документацию, потому что вам может потребоваться включить один или несколько позиционных индексов для cts:near-query, чтобы быть точным.