Выберите несколько значений в качестве объекта в шаблоне SPARQL

В SPARQL мы можем сделать что-то вроде этого

select * where {
    ?s   (_:prop1 | _:prop2)  "some_val" .
    ...
    #use ?s in other patterns
    ?s    ?o    ?p .
}

Можно ли сделать то же самое для части объекта шаблона? И каковы некоторые обходные пути этого в случае, если это невозможно?

Например:

select * where {
    ?s   _:prop ("v1" | "v2") .
    ...
    #use ?s in other patterns
    ?s    ?o    ?p .
}

Ответ 1

Есть несколько способов сделать это. Самый простой и чистый метод SPARQL 1.0 - использовать UNION, например.

SELECT * WHERE
{
  { ?s _:prop "v1" } UNION { ?s _:prop "v2" }

  # Use ?s in other patterns
}

Это, вероятно, самый простой метод, но если вам нужно несколько ограничений на ?s, это может быстро стать неудобным.

Второй метод заключается в использовании функции IN в предложении FILTER, для этого требуется реализация SPARQL 1.1, например.

SELECT * WHERE
{
  ?s _:prop ?value .
  FILTER(?value IN ("v1", "v2"))

  # Use ?s in other patterns
}

Проблема заключается в том, что использование IN может работать очень плохо, если у вас много альтернатив или много данных, которые могут быть сопоставлены ?s _:prop ?value

Третий метод заключается в использовании предложения VALUES, которое снова требует реализации SPARQL 1.1:

SELECT * WHERE
{
  VALUES (?value) { ( "v1" ) ( "v2 " ) }
  ?s _:prop ?value .

  # Use ?s in other patterns
}

Это, скорее всего, лучший вариант, поскольку он масштабируется по многим альтернативам лучше (в зависимости от реализации SPARQL) и, возможно, лучше всего читать и писать.

Ответ 2

Это хорошо работает:

SELECT *
WHERE
{
    VALUES ?value
    {
       "value1"
       "value2"
       "etc"
    }

    ?s ?p ?value
}