Запрос, чтобы получить свойства количества для определенного класса сущности - PullRequest
2 голосов
/ 04 апреля 2019

То, что я пытаюсь сделать, - это получить свойства с количественными типами свойств определенного класса (такими как Город, Страна, Человек, Река, Регион, Гора и т. Д.). Я пробовал несколько классов, таких как Country (wd:Q6256), нормально работает с запросом ниже, но многие другие классы делают запрос на превышение лимита времени. Как мне добиться результата, оптимизируя запрос ниже? или есть какой-то другой способ получить свойства типа «Кол-во» в определенном классе?

SELECT DISTINCT ?p_ ?pLabel ?pAltLabel
WHERE {
  VALUES (?class) {(wd:Q515)}
  ?x ?p_ [].
  ?x p:P31/ps:P31 ?class.

  ?p wikibase:claim ?p_.
  ?p wikibase:directClaim ?pwdt.
  ?p wikibase:propertyType ?pType.
  FILTER (?pType = wikibase:Quantity)
  SERVICE wikibase:label { bd:serviceParam wikibase:language "ko,en". }
}

1 Ответ

2 голосов
/ 05 апреля 2019

Попытка 1: оптимизация запроса

Некоторые наблюдения:

  • Вместо p:P31/ps:P31 вы можете использовать wdt:P31, что быстрее, избегая прыжка с двумя свойствами,но находит только правдивые заявления
  • Дорогая часть - это вызов службы меток в конце, что можно увидеть, комментируя эту строку, поместив # в началестрока
  • Запрос извлекает каждую заявку по каждому городу (многие!), получает свойства заявок (несколько!) и удаляет только дубликаты в конце (с DISTINCT)
  • В результате служба меток вызывается много раз для одного и того же свойства, один раз за утверждение!Это большая проблема с запросом
  • Этого можно избежать, переместив поиск свойств с DISTINCT в подзапрос и вызвав службу меток только в конце для нескольких свойств
  • После этого изменения оно должно быть быстрым, но все еще медленным, потому что оптимизатор запросов, похоже, оценивает запрос в неправильном порядке.Следуя подсказкам этой страницы , мы можем отключить оптимизатор запросов.

Это работает для меня:

SELECT ?p ?pLabel ?pAltLabel {
  hint:Query hint:optimizer "None" .
  {
    SELECT DISTINCT ?p_ {
      VALUES ?class { wd:Q515 }
      ?x wdt:P31 ?class.
      ?x ?p_ [].
    }
  }
  ?p wikibase:claim ?p_.
  ?p wikibase:propertyType ?pType.
  FILTER (?pType = wikibase:Quantity)
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

Попытка 2: разделить задачу нанесколько запросов

Узнав, что описанный выше подход не работает для некоторых самых больших категорий (например, wd:Q5, «человек»), я попробовал другой подход.Это получит все результаты, но не в одном запросе.Требуется отправить ~ 25 отдельных запросов и затем объединить результаты:

  • Мы начнем с перечисления количественных свойств.На сегодняшний день их насчитывается 503.
  • Мы хотим сохранить только те свойства, которые фактически используются для элемента типа «человек».
  • Поскольку эта проверка выполняется очень медленно (нужно просмотреть миллионы элементов), мы начинаем с проверки только первых 20 свойств из нашего списка.
  • Во втором запросе мы собираемся проверить следующие 20 и т. д.

Этот запрос проверяет первые 20 свойств:

SELECT DISTINCT ?p ?pLabel ?pAltLabel {
  hint:Query hint:optimizer "None" .
  {
    SELECT ?p ?pLabel ?pAltLabel {
      ?p wikibase:propertyType wikibase:Quantity.
      SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
    }
    OFFSET 0 LIMIT 20
  }
  ?p wikibase:claim ?p_.
  ?x ?p_ [].
  ?x wdt:P31 wd:Q5.
}

Увеличьте OFFSET до 20, 40, 60 и т. Д., До 500, чтобы проверить все свойства.

...