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 ответа:
В дополнение к ответу @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
, чтобы быть точным.