Агрегация терминов Elasticsearch и запросы

У меня есть два типа сообщений журнала:

Jul 23 09:24:16 rrr mrr-core[222]: Aweg3AOMTs_1563866656871111.mt processMTMessage() #12798 realtime: 5.684 ms

Jul 23 09:24:18 rrr mrr-core[2222]: Aweg3AOMTs_1563866656871111.0.dn processDN() #7750 realtime: 1.382 ms

Первое сообщение является типом отправленного сообщения, а второе — сообщением, подтверждающим, что сообщение было доставлено.

Разница между ними заключается в суффиксе, который я отделил от «id» и могу запросить его.

Эти сообщения анализируются и сохраняются в elasticsearch в следующем формате:

messageId: Aweg3AOMTs_1563866656871111.0.dn
text: Aweg3AOMTs
num1: 1563866656871111
num2: 0
suffix: mt/dn

Я хотел бы узнать, какие сообщения были успешно доставлены, а какие нет. Я очень новичок в elasticsearch, поэтому я действительно борюсь.

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

GET /my_index3/_search
{
  "size": 0,
  "aggs": {
    "num1": {
      "terms": {
        "field": "messageId.keyword",
        "include": ".*mt*."
      }
    }
  } 
}

Который показывает мне отправленные сообщения. Я не знаю, как добавить туда какой-то фильтр или пункт, который мог бы показывать мне только сообщения с суффиксами mt и dn.

Если у кого есть идеи, буду очень признателен :))


person vladpoverin    schedule 29.07.2019    source источник


Ответы (1)


Запускать агрегацию терминов для messageId.keyword не так уж и хорошо, так как каждое сообщение отличается («Aweg3AOMTs_1563866656871111.0.dn» — это не то же самое, что «Aweg3AOMTs_1563866656871111.mt»).

Глядя на структуру документов, я думаю, вам лучше запустить агрегацию терминов в num1, которая является общей частью сообщений .mt и .dn. Эта агрегация даст вам количество сообщений для каждого уникального num1. Таким образом, для каждого сообщения, которое получило запрос и ответ, счетчик будет равен 2, а сообщение только с запросом будет иметь счетчик 1.

Если вы также хотите увидеть само число, вы можете добавить внутрь вложенную агрегацию, например агрегацию топ-хитов с размером 1, которая будет отображать поле num1 внутри:

GET /my_index3/_search {
"size": 0,
"aggs": {
    "num1": {
        "terms": {
            "field": "num1",
            "order": {
                "_count": "desc"
            },
            "aggs": {
                "count_of_distinct_suffix": {
                    "cardinality": {
                        "field": "suffix"
                    },
                    "aggs": {
                        "filter_count_is_2": {
                            "bucket_selector": {
                                "buckets_path": {
                                    "the_doc_count": "_count"
                                },
                                "script": "the_doc_count == 2"
                            }
                        }
                    }
                }
            }
          }
       }
    }
}
person Opster Elasticsearch Expert    schedule 29.07.2019
comment
Спасибо за ответ!! Итак, как я могу получить только те сообщения, которые совпадают, чтобы они имели суффикс mt и dn? Как я могу управлять счетом 2, о котором вы говорите... Присланный вами код показывает все значения num1. - person vladpoverin; 29.07.2019
comment
Вам нужно добавить сортировку (по убыванию). - person Opster Elasticsearch Expert; 30.07.2019
comment
Я обновил условия gg выше, чтобы включить сортировку. теперь первые элементы, которые вы получите в списке, будут со значением count=2, и только после них вы увидите элементы со значением count=1. вы также можете изменить порядок сортировки, если хотите получить те, у которых count=1 раньше. Итак, пока количество пар журналов не слишком велико, вы можете получить их все и отфильтровать нужные. - person Opster Elasticsearch Expert; 30.07.2019
comment
Спасибо за помощь! Но я до сих пор не знаю, как я могу отфильтровать num1, у которых есть ошибка (суффикс «dn» и «mt»): - person vladpoverin; 30.07.2019
comment
Если я вас лучше понимаю, есть несколько сообщений с одинаковым «num1», у некоторых есть суффикс «dn», а у некоторых «mt». Таким образом, вы можете добавить внутреннюю вложенную агрегацию — кардинальность, которая подсчитывает, сколько существует различных суффиксов — должна быть либо 1, либо 2. Я обновил запрос выше. - person Opster Elasticsearch Expert; 30.07.2019
comment
Это просто дает мне все num1, которые я сохранил. Мне нужно найти только num1 с суффиксами dn и mt одновременно! Это цель :D - person vladpoverin; 30.07.2019
comment
Извините, я, вероятно, все еще не понимаю вас полностью :) то, как мой запрос строит его сначала агрегирует на основе значений num1, поэтому верхний уровень группирует каждый документ count с одним и тем же значением num1. затем в каждом ведре подсчитывается, сколько существует различных уникальных суффиксов, поэтому, если внутренний счетчик agg равен 2, это означает, что для одного и того же значения num1 есть 2 разных суффикса, что похоже на то, что вы написали, имеют суффиксы dn и mt одновременно так что, как я понял, это именно так. - person Opster Elasticsearch Expert; 30.07.2019
comment
О, теперь я вижу. Извините, это мой первый опыт поиска в elasticsearch, поэтому я еще многого не знаю. Теперь я знаю, что вы имели в виду, но есть ли возможность увидеть ТОЛЬКО результаты, где count_of_distinct_suffix равен 2? Я попытался добавить min_doc_count = 2 в конце запроса, но это не сработало :( - person vladpoverin; 30.07.2019
comment
для этого вы можете использовать селектор корзины: elastic.co/guide/en/elasticsearch/reference/current/ (см. пример здесь: discuss.elastic.co/t/) - person Opster Elasticsearch Expert; 31.07.2019
comment
Я обновил исходный ответ, чтобы добавить фильтрацию для count == 2, например - person Opster Elasticsearch Expert; 31.07.2019
comment
Зив, большое спасибо, ты спаситель. К сожалению, когда я пытаюсь запустить код, возникает ошибка: агрегатор [count_of_distinct_suffix] типа [cardinality] не может принимать субагрегации. - person vladpoverin; 31.07.2019
comment
Таким образом, вам нужно поместить селектор ведра в качестве подгруппы агрегации терминов. См. пример терминов+селектор здесь: elastic. co/guide/en/elasticsearch/reference/current/ - person Opster Elasticsearch Expert; 31.07.2019
comment
Теперь он работает просто отлично! Возникла проблема с брекетами. Есть ли возможность сделать диапазон времени для получения второго суффикса. Я имею в виду, что num1 имеет только 1 суффикс, и если тот же num1 не получит второй суффикс в течение некоторого времени, например, одного часа, он не покажет это ведро, даже если the_doc_count == 2 - person vladpoverin; 31.07.2019
comment
Пожалуйста. Несколько вариантов для продолжения — либо добавьте агрегацию гистограммы даты более высокого уровня в качестве верхнего уровня, таким образом вы можете разбить интервал на почасовые/временные сегменты. вы также можете использовать составную агрегацию, чтобы просмотреть все результаты. в любом случае, это немного сложнее, так как разделение на ведра может привести к тому, что один суффикс будет в одном ведре, а второй в следующем ведре, и они будут выглядеть так, как будто пары нет, потому что пара разделена между ведрами. Я предлагаю, если у вас есть еще вопросы, открыть новую тему, так как она слишком длинная. удачи - person Opster Elasticsearch Expert; 01.08.2019