Elasticsearch - подсчитать количество вхождений ключевых слов в документ - PullRequest
1 голос
/ 08 июля 2019

База данных: Elasticsearch v7.2
Приложение: Laravel v5.7
Использование Elasticsearch / Elasticsearch (https://github.com/elastic/elasticsearch-php) Официальная PHP-библиотека

У меня есть запрос query_string для Elasticsearch с этимкод для извлечения документов с определенной фразой при поиске по всему индексу

[
    "query_string" => [
        "default_field" => $content,
        "query" => $keywords
    ]
],

, а переменная $keywords содержит:

("MCU" OR "Marvel" OR "Spiderman")

Теперь я хочу сосчитать КОЛИЧЕСТВО ПРОИЗВЕДЕНИЙ этих слов в документах, которые я собираюсь получить

Я использовал запрос aggs с этим:

'aggs' => [
    'count' => [
        'terms' => [
            'field' => 'content.keyword'
        ]
    ]
]

Однако я понятия не имею, каксвязать эти doc_count и отобразить их соответствующим образом с попаданиями - потому что ключом является сам контент, а не идентификаторы

enter image description here

Я планирую показать весь документ и указать, сколько раз $keywords выше встречалось в каждом документе как Mentions

enter image description here Есть ли другой способ подсчетаслучаев без использования aggs в Elasticsearch

Ответы [ 3 ]

1 голос
/ 08 июля 2019

Если вы хотите только подсчитать вхождения ключевых слов, то вам не нужно включать fielddata, попробуйте фильтры фильтров вместе с вашим запросом

GET my_index/_search
{
  "query": {
    "query_string": {
      "default_field": "content", 
      "query": "MCU OR Marvel OR Spiderman"
    }
  },
  "aggs": {
    "count": {
      "filters": {
        "filters": {
          "mcu": {
            "match": {
              "content": "MCU"
            }
          },
          "marvel": {
            "match": {
              "content": "Marvel"
            }
          },
          "spiderman": {
            "match": {
              "content": "Spiderman"
            }
          }
        }
      }
    }
  }
}

Результат с beкак показано ниже:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 1.219939,
    "hits": [
      ....
      ....
    ]
  },
  "aggregations": {
    "count": {
      "buckets": {
        "marvel": {
          "doc_count": 2
        },
        "mcu": {
          "doc_count": 2
        },
        "spiderman": {
          "doc_count": 1
        }
      }
    }
  }
}

Источник: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html

0 голосов
/ 15 июля 2019

Благодаря сэру @AshrafulIslam, я смог придумать функцию Elasticsearch под названием highlights.Хотя highlights буквально подчеркивает возникающие ключевые слова, я прибегнул к PHP-функции substr_count() для подсчета тегов <em>

. Я добавил этот код в качестве родственного элемента ['body']['query']:

"highlight" => [
    "fields" => [
        "content" => ["number_of_fragments" => 0]
    ],
    'require_field_match' => false
]

Затем, просматривая элемент массива ['hits']['hits'], я выполнил что-то вроде этого:

$articles = $client->search($params);
$hits = $articles['hits']['hits'];

for($i=0; $i<count($hits); $i++){
    $hits[$i]['_source']['count_mentions'] = substr_count($hits[$i]['highlight']['content'][0],"<em>");
}
0 голосов
/ 08 июля 2019

Включение Fieldata, возможно, не лучший способ включить текстовый поиск.

https://www.elastic.co/guide/en/elasticsearch/reference/current/fielddata.html#before-enabling-fielddata

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

Текстовое поле анализируется перед индексацией, чтобы можно было найти значение, например, Нью-Йорк, в поиске new или york. Агрегирование терминов в этом поле вернет новое ведро и йоркское ведро, когда вам, вероятно, понадобится одно ведро с именем New York.

Вместо этого у вас должно быть текстовое поле для полнотекстового поиска и поле неанализованного ключевого слова с включенными значениями doc_values ​​для агрегирования, как указано ниже:

PUT my_index
{
  "mappings": {
    "properties": {
      "my_field": { 
        "type": "text",
        "fields": {
          "keyword": { 
            "type": "keyword"
          }
        }
      }
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...