Как отфильтровать по совокупности? - PullRequest
0 голосов
/ 11 февраля 2019

Мне нужен запрос, который возвращает только результат с 1 сегментом.

Приведенный ниже запрос возвращает мне данные доступа посетителя, сгруппированные по дням.

{
    "size" :  0,
    "query" : {
        "filtered" : {
            "filter" : {
                "bool" : {
                    "must" : [
                        {
                            "range" : {
                                "start_time" : {
                                    "gte" : "2019-02-06 00:00:00",
                                    "lte" : "2019-02-11 23:59:59"
                                }
                            }
                        }
                    ]
                }
            }
        }
    },
    "aggs" : {
        "UNIQUE" : {
            "terms" : {
                "size" : 0,
                "field" : "username"
            },
            "aggs" : {
                "visits" : {
                    "date_histogram" : {
                        "field" : "start_time",
                        "interval" : "day",
                        "format" : "yyyy-MM-dd"
                    }
                }
            }
        }
    }
}

Мне нужно знатькоторые вернулись только один раз за период.Поэтому, когда у вас есть только 1 ведро, это ОДИН.И если он посетил более одного дня (ведра> 1), то это РЕКУРРЕНТ.

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Найдено решение:

{
    "size" :  0,
    "query" : {
        {
            "range" : {
                "start_time" : {
                    "gte" : "2019-02-11 00:00:00",
                    "lte" : "2019-02-11 23:59:59"
                }
            }
        }
    },
    "aggs" : {
        "UNIQUE" : {
            "terms" : {
                "size" : 0,
                "field" : "username"
            },
            "aggs":{
                "visit_date": {
                    "date_histogram": {
                        "field" : "start_time",
                        "interval" : "day",
                        "format" : "yyyy-MM-dd"
                    }
                },
                "count": {
                    "cardinality": {
                        "script": "new Date(doc['start_time'].value).format('yyyy-MM-dd')"
                    }
                },
                "equal_one":{  
                    "bucket_selector":{  
                        "buckets_path":{  
                            "count":"count.value"
                        },
                        "script":"count == 1"
                    }
                }
            }
        }
    }
}

Но производительность остается проблемой.В среде с около 1 миллиона записей этот запрос работает не очень хорошо.

Может быть, какой-то запрос, использующий Метрики в сценариях , решит проблему, но потребует дополнительного анализа (doc: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-scripted-metric-aggregation.html)

0 голосов
/ 12 февраля 2019

Если я правильно понимаю, вам нужен список из users, которые посещали уникальную дату или хотели посетить только один раз за определенный промежуток времени, и вам понадобятся как детали, date, так и username, чтобы быть в aggregation.

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

Сопоставление:

PUT mytest
{
  "mappings": {
    "mydocs": {
      "properties": {
        "username": {
          "type": "keyword"
        },
        "start_time": {
          "type": "date",
          "format": "yyyy-MM-dd"
        }
      }
    }
  }
}

Образцы документов:

Вы можете видеть, что я создал 6 документов, в которых John дважды посещал в одну и ту же дату, Джек посещал сайт в две разные даты, а Jane и Rob посещал только один раз за тот период времени, за которыйЯ напишу агрегацию.

POST mytest/mydocs/1
{
  "username": "john",
  "start_time": "2018-08-01"
}

POST mytest/mydocs/2
{
  "username": "john",
  "start_time": "2018-08-01"
}

POST mytest/mydocs/3
{
  "username": "jane",
  "start_time": "2018-08-01"
}

POST mytest/mydocs/4
{
  "username": "rob",
  "start_time": "2018-08-01"
}

POST mytest/mydocs/5
{
  "username": "jack",
  "start_time": "2018-08-01"
}

POST mytest/mydocs/6
{
  "username": "jack",
  "start_time": "2018-08-02"
}

Обновлен запрос агрегирования

Примечание Я добавил еще два документа с именем пользователя Jack, которые посещают сайт в в две разные даты , имя пользователя John посещает сайт дважды в одну и ту же дату .

POST mytest/_search
{
  "size": 0,
  "query": {
    "range": {
      "start_time": {
        "gte": "2017-08-01",
        "lte": "2019-08-01"
      }
    }
  },
  "aggs": {
    "myterms": {
      "terms": {
        "size": 100,
        "field": "username"
      },
      "aggs": {
        "visit_date": {
          "date_histogram": {
            "field": "start_time",
            "interval" : "day",
            "format" : "yyyy-MM-dd"
          }
        },
        "count": {
          "cardinality": {
            "field": "start_time"
          }
        },
        "equal_one":{  
          "bucket_selector":{  
            "buckets_path":{  
             "count":"count.value"
            },
            "script":"params.count == 1"
          }
        }
      }
    }
  }
}

Ответ

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 6,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "myterms": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "john",
          "doc_count": 2,
          "count": {
            "value": 1
          },
          "visit_date": {
            "buckets": [
              {
                "key_as_string": "2018-08-01",
                "key": 1533081600000,
                "doc_count": 2
              }
            ]
          }
        },
        {
          "key": "jane",
          "doc_count": 1,
          "count": {
            "value": 1
          },
          "visit_date": {
            "buckets": [
              {
                "key_as_string": "2018-08-01",
                "key": 1533081600000,
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "rob",
          "doc_count": 1,
          "count": {
            "value": 1
          },
          "visit_date": {
            "buckets": [
              {
                "key_as_string": "2018-08-01",
                "key": 1533081600000,
                "doc_count": 1
              }
            ]
          }
        }
      ]
    }
  }
}

Вы видите, что Джон теперь появляется в результатекак и ожидалось, даже если он посещал сайт несколько раз в одну и ту же дату.

Дайте мне знать, если у вас есть какие-либо вопросы.

...