2017-01-26 5 views
1

В продолжении к вопросу: MarkLogic - getting distinct valuesMarkLogic - Улучшение запроса

У меня есть структура документа, как это:

<document> 
<question_item> 
    <question>What is your name?</question> 
    <answer>Barney Rubble</answer> 
</question_item> 
<question_item> 
    <question>What is your address?</question> 
    <answer>Bedrock</answer> 
</question_item> 
... 
</document> 

Благодаря полученному ответ на другой вопрос, теперь я могу перечислить все различные вопросы порядок частоты как таковые:

for $v in cts:element-values(xs:QName('question'),(),(), 
    cts:element-word-query(xs:QName('question'), 'name')) 
where cts:contains($v, cts:word-query('name')) 
order by cts:frequency($v) 
return concat($v,concat("-",cts:frequency($v))) 

Я хотел бы иметь возможность также включать с каждым отдельным вопросом, верхними х наиболее распространенными ответами и их подсчетом, например, Барни Щебень (100), Фред Флинтстон (59) и т. Д.

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

Любая помощь с благодарностью. Благодаря!

+0

Роберт, эти функции очень просты, если вам не нужно масштабировать. Некоторое представление о вашем масштабе может помочь нам ответить на вопрос. Сколько документов у вас есть? Сколько узлов? Примерно, сколько будет соответствовать исходному запросу? Примерно, сколько будет соответствовать второму запросу («x наиболее распространенные ответы»)? Вам нужно показать ответ на второй запрос только для верхних совпадений, видимых в gui? –

ответ

4

Ключ предназначен для использования единого индекса диапазона для этого типа огранки. Однако для текущей модели требуется фильтрация, что делает ее неэффективной для вашей цели.

Ниже приведены некоторые варианты для изучения. Если бы я не мог изменить свою модель, я бы, вероятно, пошел бы с 1.1

Вариант 1)
Чтобы ответить на этот вопрос, я, возможно, подумал о моделировании данных по-разному (все ответы на отдельный вопрос в одном документе за вопрос Затем, с индексом одного диапазона, я мог бы получить результат, рассматривая это как фасет. (Давая результат, который вы хотите, используя индекс в памяти.

Вариант 1.1)
Вы также можете сохранить свои данные как является и по-прежнему создает эти таблицы, упрощающие грань, после создания опроса. Де-нормализованные данные не являются плохими, когда они служат для достижения такой цели, как уменьшение сложности кода или повышение производительности.

Вариант 2)
Оставьте данные как есть и добавьте корень фрагмента в элемент вопроса вопроса. Это позволяет MarkLogic обрабатывать каждый из этих небольших фрагментов XML отдельно. Если вы добавите индекс диапазона по этому вопросу, а другой ответ, то вы сможете быстро перебрать все вопросы и получить нужные ответы. Это приведет к тому, что количество мелких фрагментов в системе взорвется (по одному на каждый ответ). Это жизнеспособное решение, но я бы избегал, если бы я мог повторно моделировать данные.

Вариант 3)
Если у вас есть конечное число вопросов, то вы можете также: добавить идентификатор, чтобы идентифицировать уникальные вопросы:

<question_item question-key="q1"> 
    <question>What is your address?</question> 
    <answer>Bedrock</answer> 
    </question_item> 

Тогда для каждого вопроса, добавьте индекс пробега на пути, такие как:

//question-item[@question-key="q1"]/answer 
//question-item[@question-key="q2"]/answer 
... 
//question-item[@question-key="qn"]/answer 

Затем вы можете применить подход фасета к каждому ответу. Но, как вы можете видеть - если количество вопросов больше, чем горстка, это станет громоздким, граничащим с глупостью.

2

Чтобы подробно рассказать о ответе Дэвида Энниса, в конечном счете, если вы хотите иметь возможность «входить» в индексы, где вы можете запрашивать ответы на основе результатов другого запроса, будет проще иметь только один вопрос + ответ на документ/фрагмент.

Используя вашу текущую схему и задав набор значений вопроса, если вы проиндексируете ответы, уровень фильтрации, который вы получите из индекса, остановится на детализации вашего документа/фрагмента. Таким образом, вы сможете указывать только «каждый ответ в любом документе, содержащий вопрос, равный заданному значению». Затем, так как ваш следующий шаг фильтрации основан на вопросе, к которому принадлежит ответ, вы застреваете, поскольку у вас есть только строки ответов без контекста.

Без корней фрагментов или ремоделирования XML решение будет включать: 1) получение каждого документа, соответствующего списку вопросов, 2) фильтрацию ложных положительных вопросов из документа и 3) подсчет ответов. Если вы ожидаете, что шаг 1 вернет только небольшое количество документов, то производительность, вероятно, будет прекрасной. В противном случае вы могли бы увидеть, как IO-перехват, где данные не кэшируются и должны быть извлечены с диска.

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