Многокритериальный поиск по времени - PullRequest
0 голосов
/ 28 мая 2018

Я ищу элегантный и масштабируемый способ поиска метаинформации некоторых сущностей во времени.

Давайте рассмотрим следующую мета-перемену, изменяющуюся со временем для сущностей A и B

[{
    "idEntity": "A",
    "name": "Name of A",
    "rating": 0.5,
    "description": "Some short description of A",
    "createdAtWeek": 1
}, {
    "idEntity": "B",
    "name": "Name of B",
    "rating": 0.2,
    "description": "Some short description of B",
    "createdAtWeek": 1
}, {
    "idEntity": "A",
    "name": "Name of A improved",
    "rating": 0.5,
    "description": "Some longer description of A",
    "createdAtWeek": 2
}, {
    "idEntity": "A",
    "name": "Name of A improved",
    "rating": 0.6,
    "description": "Some longer description of A",
    "createdAtWeek": 3
}]

Я хочу иметь возможность найти сущности (уникальные), для которых последняя мета соответствует rating >= 0.2 и которые содержат слово of в их description.Я также хочу, чтобы в прошлом я мог искать тот же критерий, но это могло бы дать мне другой результат.

Самый простой способ сделать это через Mongo - это создать конвейер агрегации, ноэто слишком медленно, если коллекция становится большой.

Поэтому я пошел и продублировал все документы, чтобы каждую неделю (1-3) получал свои полные данные, что позволяет мне напрямую включать createdAtWeek в запроси будьте уверены, что у меня стабильные результаты во времени.

Но вы можете видеть, к чему это приводит, огромное дублирование делает коллекцию огромной впустую.

Поэтому я попытался взглянуть на хранение этих документов в Solr, но при просмотре документации, похоже, нет способа сначала сгруппировать результаты по сущности и дате, а затем выполнить поиск внутри группировки.

Есть ли другой способ достижения тех же результатов, что и при дублированиибез фактического дублирования?

1 Ответ

0 голосов
/ 28 мая 2018

Solr Block Join Query Parser может обрабатывать такие операции.

Структура данных изменяется в сторону иерархической системы, а createdAtWeek заменяется на validSince_i и validUntil_i.

/* Entity A */
{
  "path_s": "1.entity",
  "id": "A",
  "_childDocuments_": [
    {
      "path_s": "2.metadata.rating",
      "id": "2.metadata.rating.1",
      "_childDocuments_": [
        {
          "path_s": "3.metadata.rating.timeValidity",
          "id": "2.metadata.rating.timeValidity.1",
          "validSince_i": -1,
          "validUntil_i": 2,
          "value_f": 0.5
        },
        {
          "path_s": "3.metadata.rating.timeValidity",
          "id": "2.metadata.rating.timeValidity.2",
          "validSince_i": 3,
          "validUntil_i": 9999999,
          "value_f": 0.6
        }
      ]
    },
    {
      "path_s": "2.metadata.description",
      "id": "2.metadata.description.1",
      "_childDocuments_": [
        {
          "path_s": "3.metadata.description.timeValidity",
          "id": "2.metadata.description.timeValidity.1",
          "validSince_i": -1,
          "validUntil_i": 1,
          "value_txt_en": "Some short description of A"
        },
        {
          "path_s": "3.metadata.description.timeValidity",
          "id": "2.metadata.description.timeValidity.2",
          "validSince_i": 2,
          "validUntil_i": 9999999,
          "value_txt_en": "Some longer description of A"
        }
      ]
    }
  ]
}
/* Entity B */
{
  "path_s": "1.entity",
  "id": "B",
  "_childDocuments_": [
    {
      "path_s": "2.metadata.rating",
      "id": "2.metadata.rating.2",
      "_childDocuments_": [
        {
          "path_s": "3.metadata.rating.timeValidity",
          "id": "2.metadata.rating.timeValidity.3",
          "validSince_i": -1,
          "validUntil_i": 9999999,
          "value_f": 0.2
        }
      ]
    }
  ]
}

BlockJoin теперь можно использовать с фасеткой, если timeValidities не перекрывают друг друга, например:

fq={!parent which="path_s:1.entity"}(path_s:3.metadata.rating.timeValidity AND validUntil_i:[2 TO *] AND value_f:[0.3 TO *])&fq={!parent which="path_s:1.entity"}(path_s:3.metadata.description.timeValidity AND validUntil_i:[2 TO *] AND value_txt_en:short)&q=*:*

, который не возвращает сущностей, так как нет сущностей после недели 2, которые имеютrating >= 0.3 с описанием, содержащим short

Выполнение следующего тоже отлично работает

fq={!parent which="path_s:1.entity"}(path_s:3.metadata.rating.timeValidity AND validUntil_i:[2 TO *] AND value_f:[0.3 TO *])&fq={!parent which="path_s:1.entity"}(path_s:3.metadata.description.timeValidity AND validUntil_i:[2 TO *] AND value_txt_en:longer)&q=*:*

Как вы можете видеть, сущность A отображается, так как ее рейтинг>> 0,3 после недели> =2 с описанием, содержащим longer.

Необходимо подтвердить аспект производительности, но он выполняет свою работу и избегает дублирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...