Можно ли выполнять поиск по шаблонам для троек с помощью запроса cts
?
Я пробовал в sparql
, получаю правильные результаты, но запрос выполняется очень медленно.
Например:
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
select ?iri
where {
?iri skos:prefLabel ?prefLabel .
filter (STRSTARTS(lcase(?prefLabel), 'soviet'))
} limit 250
Вышеупомянутый запрос возвращает мне правильные результаты, но запрос выполняется очень медленно.
Поскольку я создаю API автоматического предложения, и он должен быть очень быстрым.
Пожалуйста помоги.
Обновление после комментария daves:
Я попробовал второй подход, он лучше предыдущего, но не так быстро.
Запрос cts filtered
выполняется немного медленно, мы не можем выполнить поиск unfiltered
в текущей структуре xml.
В проекте нам нужно, чтобы предложения были очень быстрыми, поэтому для этого я попробовал следующий подход.
Я создал файлы XML, как описано ниже, для каждой темы
<record>
<pref-label>Dixit Singla</pref-label>
<iri>prefix:12345</iri>
</record>
Теперь, используя cts:element-values on iri element
и фильтруя его с помощью wildcarded cts:element-value-query on pref-label
, я получаю все согласованные радужные оболочки и передаю их в запрос sparql. Благодаря этому я вижу значительное улучшение производительности.
cts:element-values(xs:QName('iri'), (),(), cts:element-value-query(xs:QName('pref-label'), 'sov* *'))
Я знаю, что приведенный выше подход потребует больше памяти, но это нормально, так как производительность действительно хорошая :)
Наблюдение: при сдаче предметов в sparql
он работает очень быстро.
нравиться:
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
select ?iri
where {
values ?iri {prefix:12345 prefix:12346 prefix:12339 prefix:12345}
?iri skos:prefLabel ?prefLabel .
#apply filters
} limit 250
хорошо, cts:contains
изначально работает в SPARQL. Вы можете попробовать, возможен ли cts:search
, и тогда использовать выражение XQuery. У меня здесь нет сервера Marklogic
XPath через префикс fn:
также возможен, но если здесь не используется полнотекстовый индекс, проверка начала строки все равно будет дорогостоящей.
Вы используете управляемые или встроенные тройки?
Управляемые тройки.
Два подхода, перечисленные в этом ответе
Попробуй это:
sem:sparql(
"PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
select ?iri
where {
?iri skos:prefLabel ?prefLabel .
filter (STRSTARTS(lcase(?prefLabel), 'soviet'))
} limit 250",
(),
(),
sem:store("any", cts:element-query(xs:QName("sem:object"), cts:word-query("soviet*")))
)
sem:store
идентифицирует набор троек. Передав слово-запрос, мы находим только те тройки, которые встречаются в документах, содержащих <sem:object>
, который начинается с слова «советский».
Даже управляемые тройки отображаются в документах как XML или JSON. Когда вы вставляете управляемые тройки, MarkLogic решает, как разделить их на файлы. Если у вас много троек, этот подход должен сократить количество, с которым выполняется запрос SPARQL.
правки на основе комментариев @ grtjn:
sem:store
.Второй подход. Цель состоит в том, чтобы выполнить поиск по подстановочным знакам для объектов, затем получить IRI субъектов и передать их в запрос SPARQL.
Поскольку это управляемые тройки, мы знаем, что они будут в XML-документах с корнем sem:triples
, и каждая тройка будет представлена следующим образом:
<sem:triple>
<sem:subject>http://example.com/my-subject</sem:subject>
<sem:predicate>http://example.com/my-predicate</sem:predicate>
<sem:object datatype = "http://www.w3.org/2001/XMLSchema#string">my-object</sem:object>
</sem:triple>
Мы можем создать запрос с подстановочными знаками, нацеленный на строки объекта:
cts:element-value-query(xs:QName("sem:object"), "soviet *", "wildcarded")
Обратите внимание на пробел между «советским» и «*». Документы для cts:element-value-query
объясняют, почему:
Note that the text content for the value in a cts:element-value-query is treated the same as a phrase in a cts:word-query, where the phrase is the element value. Therefore, any wildcard and/or stemming rules are treated like a phrase. For example, if you have an element value of "hello friend" with wildcarding enabled for a query, a cts:element-value-query for "he*" will not match because the wildcard matches do not span word boundaries, but a cts:element-value-query for "hello " will match. A search for "" will match, because a "*" wildcard by itself is defined to match the value. Similarly, stemming rules are applied to each term, so a search for "hello friends" would match when stemming is enabled for the query because "friends" matches "friend".
Вместо этого вы можете использовать cts:element-word-query
.
Затем мы можем использовать параметр $expression
на cts:search
, чтобы убедиться, что мы получаем только те тройки, которые нам нужны. Обратите внимание, что для этого требуется фильтрация. Когда у нас есть тройки, мы можем использовать XPath для получения предметов, а затем передать их в запрос SPARQL.
Собирая все вместе, получаем:
let $query := cts:element-value-query(xs:QName("sem:object"), "soviet *")
let $subjects := cts:search(/sem:triples/sem:triple, $query)/sem:subject/fn:string()
Передайте свой $subjects
в запрос SPARQL и вперед. Это должно сработать; вопрос, с которым я остаюсь, заключается в том, будет ли он быстрее, чем то, с чего вы начали. Мне было бы интересно услышать результаты вашего тестирования.
Разве это не должно быть "soviet*"
?
Sem: store с cts: query может значительно сократить количество троек, оцениваемых механизмом sparql, значительно улучшая производительность, но будьте осторожны, чтобы не исключить тройки, которые могут вам понадобиться. Нет никаких гарантий относительно того, какие тройки сохраняются, а какие тройки «управляются» MarkLogic.
@dave Спасибо за ваш ответ, но я не могу использовать 'store', так как мне нужно подключаться и к другим триплетам (как вы уже упоминали), и мне нужно фильтровать тройки по некоторым другим предикатам, а также в sparql. Есть ли другой способ, например, использование возможностей cts:search wildcarded
для получения IRI субъектов и передачи этих iris в запросе sparql.
@DixitSingla см. Второй подход выше
@DaveCassel Я пробовал второй подход. Пожалуйста, ознакомьтесь с разделом «Обновление после комментариев».
без полнотекстового индекса вы в основном теряетесь в SPARQL, поскольку необходимо выполнить полное сканирование + фильтрацию промежуточного результата. Marklogic поддерживает функции полнотекстового поиска? если так, просто используйте это