Elasticsearch: общая частота и количество документов из данного набора документов

Я пытаюсь получить общее количество терминов и количество документов из данного набора документов, но _termvectors в asticsearch возвращает ttf и doc_count из всех документов в индексе. Есть ли способ, чтобы я мог указать список документов (идентификаторы документов), чтобы результат был основан только на этих документах.

Ниже приведены детали документов и запрос, чтобы получить общую частоту:

Детали индекса:

PUT /twitter
{ "mappings": {
    "tweets": {
      "properties": {
        "name": {
          "type": "text",
          "analyzer":"english"
        }
      }
    }
  },
  "settings" : {
    "index" : {
      "number_of_shards" : 1,
      "number_of_replicas" : 0
    }
  }
}

Детали документа:

PUT /twitter/tweets/1
{
  "name":"Hello bar"
}

PUT /twitter/tweets/2
{
  "name":"Hello foo"
}

PUT /twitter/tweets/3
{
  "name":"Hello foo bar"
}

Он создаст три документа с идентификаторами 1, 2 и 3. Теперь предположим, что твиты с идентификаторами 1 и 2 принадлежат user1, а 3 принадлежат другому пользователю, и я хочу получить термин-вектор для user1.

Запрос, чтобы получить этот результат:

GET /twitter/tweets/_mtermvectors
{
  "ids" : ["1", "2"],
  "parameters": {
      "fields": ["name"],
      "term_statistics": true,
      "offsets":false,
      "payloads":false,
      "positions":false
  }
}

Отклик:

    {
  "docs": [
    {
      "_index": "twitter",
      "_type": "tweets",
      "_id": "1",
      "_version": 1,
      "found": true,
      "took": 1,
      "term_vectors": {
        "name": {
          "field_statistics": {
            "sum_doc_freq": 7,
            "doc_count": 3,
            "sum_ttf": 7
          },
          "terms": {
            "bar": {
              "doc_freq": 2,
              "ttf": 2,
              "term_freq": 1
            },
            "hello": {
              "doc_freq": 3,
              "ttf": 3,
              "term_freq": 1
            }
          }
        }
      }
    },
    {
      "_index": "twitter",
      "_type": "tweets",
      "_id": "2",
      "_version": 1,
      "found": true,
      "took": 1,
      "term_vectors": {
        "name": {
          "field_statistics": {
            "sum_doc_freq": 7,
            "doc_count": 3,
            "sum_ttf": 7
          },
          "terms": {
            "foo": {
              "doc_freq": 2,
              "ttf": 2,
              "term_freq": 1
            },
            "hello": {
              "doc_freq": 3,
              "ttf": 3,
              "term_freq": 1
            }
          }
        }
      }
    }
  ]
}

Здесь мы можем видеть hello имеет doc_count 3 и ttf 3. Как я могу сделать это, чтобы рассматривать только документы с данными идентификаторами.

Я думаю, что один из подходов - создать разные индексы для разных пользователей. Но я не уверен, что этот подход правильный. При таком подходе индексы будут увеличиваться с пользователями. Или может быть другое решение?

1 ответ

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

Вам нужно будет включить fielddata в отображении поля (хотя это может стать жестким в памяти, проверьте страницу документации о fielddata Больше подробностей):

PUT /twitter
{ 
  "mappings": {
    "tweets": {
      "properties": {
        "name": {
          "type": "text",
          "analyzer":"english",
          "fielddata": true,
          "term_vector": "yes"
        }
      }
    }
  }
}

Тогда используйте terms агрегация:

POST /twitter/tweets/_search
{
  "size": 0,
  "query": {
    "terms": {
      "_id": [
        "1",
        "2"
      ]
    }
  },
  "aggs": {
    "my_term_doc_count": {
      "terms": {
        "field": "name"
      }
    }
  }
}

Ответ будет:

{
  "hits": ...,
  "aggregations": {
    "my_term_doc_count": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "hello",
          "doc_count": 2
        },
        {
          "key": "bar",
          "doc_count": 1
        },
        {
          "key": "foo",
          "doc_count": 1
        }
      ]
    }
  }
}

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

Я бы предложил вычислять векторы терминов в автономном режиме с _analyze API и хранить их в отдельном индексе явно. Таким образом, вы сможете использовать простые агрегации для вычисления также общей частоты слагаемых. Здесь я показываю пример использования _analyze API.

POST twitter/_analyze
{
  "text": "Hello foo bar"
}

{
  "tokens": [
    {
      "token": "hello",
      "start_offset": 0,
      "end_offset": 5,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "foo",
      "start_offset": 6,
      "end_offset": 9,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "bar",
      "start_offset": 10,
      "end_offset": 13,
      "type": "<ALPHANUM>",
      "position": 2
    }
  ]
}

Надеюсь, это поможет!

Другие вопросы по тегам