Как написать SPARQL-запрос, который эффективно сопоставляет строковые литералы, игнорируя регистр

Я использую Jena ARQ для написания SPARQL-запроса к большой онтологии, читаемой из Jena TDB, чтобы найти типы, связанные с концепциями на основе метки rdfs:

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> "aspirin" .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}

Это работает довольно хорошо и на самом деле довольно быстро (<1 секунды). К сожалению, для некоторых терминов мне нужно выполнить этот запрос без учета регистра. Например, потому что метка"Tylenol" в онтологии, но не"tylenol", следующий запрос будет пустым:

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> "tylenol" .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}

Я могу написать регистронезависимую версию этого запроса, используя синтаксис FILTER, например:

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
 FILTER ( regex (str(?term), "tylenol", "i") )
}

Но теперь запрос занимает больше минуты! Есть ли способ написать запрос без учета регистра более эффективным способом?

 lmsurprenant21 мая 2012 г., 20:09
@ SteveHarris Я обновил вопрос, чтобы включить технологии, которые я использую. Первоначально я надеялся, что мне просто не хватает какой-то функции SPARQL, но теперь я думаю, что мне нужно будет изучить варианты индексации текста, как вы предлагаете, так что спасибо за подсказку.
 Steve Harris19 мая 2012 г., 06:07
Вы не говорите, какое программное обеспечение вы используете. Во многих хранилищах RDF есть опции индексации текста, которые более эффективны для текстового поиска, чем regex ().

Ответы на вопрос(2)

которые вы можете использовать в SPARQL,regex, наверное, самый дорогой. Ваш запрос может выполняться быстрее, если вы избегаетеregex и вы используетеUCASE илиLCASE на обеих сторонах теста. Что-то типа

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
 FILTER (lcase(str(?term)) = "tylenol")
}

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

 Joshua Taylor07 дек. 2013 г., 19:06
Когда я увидел этот вопрос, это именно тот ответ, который я искал. Нормализация строк (путем уменьшения регистра) и проверка должны выполняться значительно быстрее, чем запрос регулярного выражения. + 1.
 lmsurprenant21 мая 2012 г., 19:58
Возможно, он был немного быстрее, но все же был на несколько порядков медленнее, чем версия без фильтра. Спасибо за вдумчивый ответ, но мне, возможно, придется изучить параметры индексации строк.
 Manuel Salvadores21 мая 2012 г., 21:13
Моя рекомендация будет 4store.org / ПРОФ / вики / TextIndexing
Решение Вопроса

по которой запрос с запросом FILTER выполняется медленнее, заключается в том, что? Term не связан, поэтому требуется сканирование индекса PSO или POS, чтобы найти все операторы с предикатом rdfs: label и отфильтровать их по регулярному выражению. Когда он был привязан к конкретному ресурсу (в вашем первом примере), он мог использовать индекс OPS или POS для сканирования только операторов с предикатом rdfs: label и указанным ресурсом объекта, который имел бы гораздо меньшую мощность.

Распространенным решением проблемы текстового поиска такого типа является использование внешнего текстового индекса. В этом случае Jena предоставляет свободный текстовый индекс под названием LARQ, который использует Lucene для выполнения поиска и объединяет результаты с остальной частью запроса.

 Joshua Taylor07 дек. 2013 г., 19:08
Этот ответ верен, но он не дает простейшего ответа на вопрос ОП: «Есть ли способ написать запрос без учета регистра более эффективным способом?» ответ msalvadores показывает, что есть способ более эффективный, чемregex.

Ваш ответ на вопрос