2016-03-23 2 views
3

У меня есть следующий CTS поисковый запрос:CTS и xPath оба необходимы?

cts:search(/parent, 
    cts:and-query((
     cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'), 
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'), 
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3') 
    )) 
)/child[@attr-1 eq 'value-2' and @attr-2 eq "value-3"] 

(: Returns /parent/child elements matching criteria :) 

У меня есть несколько классификаторов на родителей, а также отборочные на детей. Конечный результат, который я хочу, это только дети. Для того, чтобы сделать это, как вы можете видеть сверху, я должен:

  • Поиск документов, которые соответствуют критериям родителя + критерии дети
  • После получения этого документа, отфильтровать детей по тем же критериям логики как указано выше

Это работает, но кажется очень глупым, что у меня должна быть такая же логика в запросе cts: как и у xPath для детей. Логика дублируется без необходимости.

Есть ли способ, которым я могу сделать это все в cts: query, и не должен иметь дополнительных выражений xPath, как в примере выше?


Это похоже на то, что я хочу, но он не работает для задачи, указанной в комментариях:

cts:search(/parent/child, 
    cts:and-query((
     cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'), (: The problem is this line... I can't filter by the parent, as it is above the scope of my first parameter (/parent/rule) :) 
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'), 
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3') 
    )) 
) 

ответ

3

Вы все еще можете запросить родителя, даже если ваш поиск по ребенок:

cts:search(/parent/child, 
    cts:and-query((
     cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'), 
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'), 
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3') 
    )) 
) 

Это будет работать как отфильтрованный поиск, но так как вы вручную делать фильтрацию в любом случае, производительность должна быть примерно эквивалентна.

Update:

Я проверил это и приведенное утверждение неверно. Я думал, что это правильно, но, видимо, фильтрация будет фильтровать результаты, которые точно не совпадают с поисковым выражением. Родитель был бы вне области видимого для поиска выражения.

В идеале, вы должны разбить свои документы на child элемент, но вы можете по крайней мере удаления дублирующих запросов и XPath, как это:

cts:search(/parent/child, 
    cts:and-query((
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'), 
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3') 
    )) 
)[parent::parent/@attr = 'value'] 
+0

Это не работает для меня. Когда у меня есть '/ parent' как выражение для поиска, я возвращаю родителя из cts: search. Когда я помещаю выражение '/ parent/child' в выражение для поиска, я ничего не получаю. Сам вопрос cts: query никогда не изменяется, все, что я меняю, - это выражение для поиска. Когда у меня есть '/ parent/child', он не работает. Мое предположение - это первый элемент-атрибут-значение-запрос на родительском, выкидывает все, так как он не находится под выражением поиска (?) – CtheGood

+0

Спасибо за ваше обновление wst. Вы также можете легко отменить логику и захватить родителя из cts: search, а затем отфильтровать дочерние элементы с помощью xPath. Там, где вы отфильтровывали детей, в моем случае на самом деле будет быстрее, поскольку это более специфично, чем родители. Я все еще надеялся (по вопросу) решить все это в cts: искать чисто стилистические причины, но, возможно, это невозможно.Является ли вычисление одинаковым для фильтрации cts: search, поскольку оно предназначено для фильтрации с помощью выражения xPath? – CtheGood

+2

@CtheGood Computationally, делая cts: поиск делает как можно больше тяжелого подъема, является лучшей стратегией. Все результаты, которые он может вернуть * нефильтрованный *, будут разрешены с использованием только индексов, поэтому они будут очень быстрыми. Если вам нужно использовать фильтрацию через cts: search или вручную через XPath, тогда база данных должна: 1) выбрать больше документов, чем это могло бы иначе, и 2) загрузить их в память для фильтрации. Нет общего правила, как максимизировать первое и минимизировать последнее - это просто зависит от ваших документов, поэтому тестирование разных подходов - это все, что вы можете сделать. – wst

1

WST дал вам ответ. Однако все это связано с необходимостью фильтрации. В MarkLogic идея состоит в том, что один документ должен отражать одну «запись». Возможно ли реорганизовать ваши документы, чтобы избежать необходимости фильтрации в первом месте?

+0

Нет, это не так. Мои документы уже очень просты, где каждый документ имеет корневой элемент только с 1 глубокими детьми (то есть ). Родитель имеет атрибуты, как и все дети. Я хочу получить только несколько целевых дочерних элементов уже целевого родителя. Мне всегда приходилось делать это с помощью двойной логики - cts: поиск по родительскому элементу, а затем фильтрация по той же логике с помощью xPath. Но я хотел бы консолидироваться. – CtheGood

+1

@CtheGood. Разрабатывая предложение Дэвида, используя реляционную аналогию, в MarkLogic лучше всего думать о документах как о строках, а не о таблицах. Для достижения идеальной производительности запроса требуется одна-единственная связь между данными, которые необходимо запросить, и одним документом. В вашем случае я мог бы сделать документ (или использовать корни фрагментов ... но будьте осторожны) и распространять (дублировать) любые данные, важные для запроса от родителя к дочерним документам. Этот тип «денормализации» является очень распространенной практикой в ​​ML. – wst

+1

И, конечно же, это баланс. Не совсем искусство, но некоторые личные решения вступают в игру. Вы также должны учитывать, что вы не хотите, чтобы в MarkLogic были крошечные фрагменты, поэтому, если дочерние документы являются «крошечными» (см. Документы для руководства), тогда их совместная упаковка до определенного размера и применение фильтрации являются жизнеспособным вариантом. Например, трижды в ML (3 элемента и родительский элемент) хранятся примерно на 100 в фрагменте, а не отдельно, когда они импортируются. –

Смежные вопросы