Как рассчитать общее количество для каждого токена в Elasticsearch
У меня есть запрос в Elastic
{
"query":{
"bool":{
"must":[
{
"query_string":{
"query":"something1 OR something2 OR something3",
"default_operator":"OR"
}
}
],
"filter":{
"range":{
"time":{
"gte":date
}
}
}
}
}
}
Я хочу рассчитать количество для каждого токена во всех документах, используя эластичный поиск в одном запросе, например:
something1: 26 documents
something2: 12 documents
something3: 1 documents
3 ответа
Предполагая, что токены не схожи с перечислениями (т. Е. Ограниченным набором определенных значений, таких как имена состояний, которые сделают объединение терминов вашей лучшей ставкой при правильном отображении), я думаю, что наиболее близким к тому, что вы хотите, будет использование фильтров агрегация:
POST your-index/_search
{
"query":{
"bool":{
"must":[
{
"query_string":{
"query":"something1 OR something2 OR something3",
"default_operator":"OR"
}
}
],
"filter":{
"range":{
"time":{
"gte":date
}
}
}
}
},
"aggs": {
"token_doc_counts": {
"filters" : {
"filters" : {
"something1" : {
"bool": {
"must": { "query_string" : { "query" : "something1" } },
"filter": { "range": { "time": { "gte": date } } }
}
},
"something2" : {
"bool": {
"must": { "query_string" : { "query" : "something2" } },
"filter": { "range": { "time": { "gte": date } } }
}
},
"something3" : {
"bool": {
"must": { "query_string" : { "query" : "something3" } },
"filter": { "range": { "time": { "gte": date } } }
}
}
}
}
}
}
}
Ответ будет выглядеть примерно так:
{
"took": 9,
"timed_out": false,
"_shards": ...,
"hits": ...,
"aggregations": {
"token_doc_counts": {
"buckets": {
"something1": {
"doc_count": 1
},
"something2": {
"doc_count": 2
},
"something3": {
"doc_count": 3
}
}
}
}
}
Вы можете разбить ваш запрос на агрегацию фильтров из трех фильтров. Для справки смотрите здесь: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html
Что вам нужно сделать, это создать поле Copy_To и иметь отображение, как показано ниже.
В зависимости от полей, которые ваш query_string
запросы, вам нужно включить некоторые или all
полей с copy_to
поле.
По умолчанию query_string
ищет все поля, поэтому вам может потребоваться указать copy_to
для всех полей, как показано ниже, где для простоты я создал только три поля, title
, field_2
и третье поле content
который будет действовать как скопированный в поле.
картографирование
PUT <your_index_name>
{
"mappings": {
"mydocs": {
"properties": {
"title": {
"type": "text",
"copy_to": "content"
},
"field_2": {
"type": "text",
"copy_to": "content"
},
"content": {
"type": "text",
"fielddata": true
}
}
}
}
}
Образцы документов
POST <your_index_name>/mydocs/1
{
"title": "something1",
"field_2": "something2"
}
POST <your_index_name>/mydocs/2
{
"title": "something2",
"field_2": "something3"
}
Запрос:
Вы получите необходимое количество документов для каждого токена, используя приведенный ниже запрос агрегации, а я использовал термины агрегации:
POST <your_index_name>/_search
{
"size": 0,
"query": {
"query_string": {
"query": "something1 OR something2 OR something3"
}
},
"aggs": {
"myaggs": {
"terms": {
"field": "content",
"include" : ["something1","something2","something3"]
}
}
}
}
Ответ на запрос:
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0,
"hits": []
},
"aggregations": {
"myaggs": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "something2",
"doc_count": 2
},
{
"key": "something1",
"doc_count": 1
},
{
"key": "something3",
"doc_count": 1
}
]
}
}
}
Дайте мне знать, если это поможет!