Ваш подход не так плох, как вы думаете. Есть только несколько изменений, необходимых для того, чтобы он работал так, как вам нравится.
Прежде всего, вам лучше использовать cts:element-value-query
вместо cts:word-query
. Это позволит вам ограничить искомые значения конкретным элементом. Это работает лучше всего, когда вы добавляете индекс диапазона элемента для этого элемента, но это не обязательно. Он также может опираться на всегда присутствующий индекс слов.
Во-вторых, cts:or-query
не требуется. Функции cts:word-query
и cts:element-value-query
(а также все другие связанные функции) принимают несколько строк поиска в качестве одного аргумента последовательности. Они автоматически обрабатываются как или запрос .
В-третьих, телефонные номера являются вашим ' первичным ключом ' в результате, поэтому возврат списка всех соответствующих элементов Phone - это путь. Вам просто нужно понять, что получившийся элемент Phone по-прежнему знает, откуда он взялся. Вы можете легко использовать XPath
для перехода к родителю и братьям и сестрам.
В-четвертых, нет ничего против циклического перебора результатов поиска. Это может звучать немного странно, но это не требует больших дополнительных затрат. На самом деле, это в значительной степени пренебрежимо мало для MarkLogic Server. Большая часть производительности может быть потеряна при попытке вернуть много результатов (более нескольких тысяч), и в этом случае большая часть времени теряется при сериализации всего этого. И если вам, вероятно, придется обрабатывать множество результатов поиска, разумно сразу начать использовать нумерацию страниц.
Чтобы получить то, что вы просите, вы можете использовать следующий код:
<results>{
for $phone in
cts:search(
doc()/Person/Phone,
cts:element-value-query(
xs:QName("Phone"),
("3738494044", "2373839383", "3933849383")
)
)
return
<match id="{data($phone/../@id)}" phone="{data($phone)}" name="{data($phone/../Name)}" city="{data($phone/../City)}"/>
}</results>
Удачи.