Value-Query внутри Element-Query
Поиск предметов, которые имеют общую высоту 4":
У меня есть вопрос об использовании cts:search. Рассмотрим следующий xml:
<Item Id="07123114-5c14-4ba9-a6ad-7b688feb8706" ...>
...
<AttributeValue AttributeName="Mounting Application" AttributeGroup="Search_Application">Tank</AttributeValue>
<AttributeValue AttributeName="Type" AttributeGroup="Search_Type">Pump Mounting Bracket</AttributeValue>
<AttributeValue AttributeName="Overall Width" AttributeGroup="Search_Width">15/16 "</AttributeValue>
<AttributeValue AttributeName="Overall Height" AttributeGroup="Search_Height">1-3/8 "</AttributeValue>
...
</Item>
Допустим, я хочу искать предметы с общей высотой = 4"
Я использую следующий запрос в CTS: поиск:
cts:search(/tx:Item,
cts:element-query(xs:QName("tx:AttributeValue"), cts:and-query((
cts:element-attribute-value-query(xs:QName("tx:AttributeValue"), xs:QName("AttributeName"), "Overall Height"),
cts:word-query("4 """, "exact"))))
)
Это дает мне все предметы, которые имеют общую высоту 4 дюйма, или 1/4 дюйма, или 3/4 дюйма и т. Д. Это потому, что слово-запрос выполняет поиск "содержит". Но я хочу точный Соответствие значения. Я не могу выполнить элемент-значение-запрос, потому что он обернут в элемент-запрос (значение-элемент не является подэлементом).
В настоящее время у нас есть две альтернативы: изменение структуры xml: вариант 1. Сделать значение атрибутом элемента AttributeValue; Вариант 2. Сделать его дочерним элементом.
Я чувствую, что должен быть способ получить то, что я ищу, без изменения структуры XML. Пожалуйста, порекомендуйте.
2 ответа
Я бы изменил XML: использовать AttributeName
генерировать значимые имена элементов.
MarkLogic предполагает, что ваш XML имеет значимые имена элементов и атрибутов. Эта структура XML выглядит как очень хороший формат сериализации. Но это плохой формат запроса, потому что имена элементов не имеют смысла. Это как таблица реляционной базы данных с тремя столбцами: тип, группа, значение. Таким образом, каждый запрос должен присоединиться WHERE TYPE=? AND VALUE=?
, Гораздо эффективнее искать значения WHERE HEIGHT=?
Таким образом, MarkLogic довольно сильно подталкивает вас в этом направлении.
Технически возможно найти способ обойти это, но вы боретесь с инструментом. Вместо этого попробуйте представить XML как модель того, как MarkLogic будет создавать свои индексы. Когда XML не легко запросить, измените его.
Ваша основная проблема в том, что токенизация будет разбита на / и пробел, и так далее, так что "2/4" содержит слово "4", которое вы и просите.
Вы могли бы достичь этого, создав поле с переопределением токенизатора (ML7), так что / является токеном слова, а пробел и "удалены". Затем вы заменяете запрос слова на запрос слова поля для данного поля.
Однако я согласен с Майклом в том, что вы окажете себе услугу, если будете внимательнее смотреть на моделирование данных.