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), так что / является токеном слова, а пробел и "удалены". Затем вы заменяете запрос слова на запрос слова поля для данного поля.

Однако я согласен с Майклом в том, что вы окажете себе услугу, если будете внимательнее смотреть на моделирование данных.

Другие вопросы по тегам