Jena ARQ возвращает непустой результат для AVG (), если нет совпадающего тройного шаблона

У меня есть запрос, в котором используется оператор AVG ():

SELECT (AVG(?z) AS ?avg) { ?x <http://ex.com/value> ?z }

Представим, что в тройном хранилище нет троек, соответствующих заданному тройному шаблону, тогда мы ожидаем (по крайней мере, у меня), что запрос должен вернуть пустой результат. И Virtuoso фактически возвращает пустой результат, вы можете использовать конечную точку DBpedia SPARQL для проверки (выполнить).

Но Fuseki и Jena ARQ возвращают непустой результат: 0. Вы можете проверить это на sparql.org (выполнить).

Можно ли настроить Jena ARQ так, чтобы он возвращал пустой результат для данного запроса? Если да, то как?


person Maksim Kolchin    schedule 14.04.2015    source источник
comment
Я не знаю, можете ли вы изменить поведение Йены, но если вы это сделаете, это будет некорректно. В спецификации говорится, что AVG () должен возвращать 0, если набор пустой.   -  person Joshua Taylor    schedule 14.04.2015


Ответы (1)


мы ожидаем (по крайней мере, я), что запрос должен вернуть пустой результат. И Virtuoso фактически возвращает пустой результат, вы можете использовать конечную точку DBpedia SPARQL для проверки.

Но Fuseki и Jena ARQ возвращают непустой результат: 0. Вы можете проверить его на sparql.org.

Я не знаю, можете изменить поведение avg, но, вероятно, не следует, потому что Йена здесь поступает правильно , и Virtuoso (конечная точка для DBpedia) делает это неправильно. Стандарт SPARQL 1.1 специально определяет, что avg возвращать, когда группа пуста:

18.5.1.4 в среднем

Функция Avg set вычисляет среднее значение для выражения по группе. Он определяется в терминах суммы и количества.

Определение: Среднее числовое Среднее (мультимножество M)

Avg (M) = "0" ^^ xsd: целое число, где Count (M) = 0

Avg (M) = Sum (M) / Count (M), где Count (M)> 0

Тем не менее, вы можете использовать if, чтобы проверить, равен ли счетчик нулю, и вернуть неопределенное значение в этом случае, а в противном случае - среднее. Это должно работать с любой конечной точкой, а не только с ARQ. Я использовал значения, чтобы ввести здесь переменную с неопределенным значением, но вы могли бы так же легко использовать выражение, которое вызовет ошибку, например, 1/0. (Конечно, существует опасность, что реализации могут расширить поведение операторов, поэтому на самом деле довольно сложно гарантировать, что какое-либо конкретное выражение будет ошибкой.)

select (if(count(?x) = 0,?undef,avg(?x)) as ?average) where {
      values ?x { 2 3 4 }
      values ?undef { undef }
}
group by ?undef

-----------
| average |
===========
| 3.0     |
-----------

And in the case where there are no values for ?x:

select (if(count(?x) = 0,?undef,avg(?x)) as ?average) where {
  values ?x {}
  values ?undef { undef }
}
group by ?undef

-----------
| average |
===========
|         |
-----------
person Joshua Taylor    schedule 14.04.2015
comment
Спасибо @ joshua-taylor за ответ! У меня есть конкретный вариант использования, поэтому я создал собственную реализацию AVG (), которую довольно легко сделать в Йене. - person Maksim Kolchin; 15.04.2015