Как выполнить объединение терминов на основе доменного имени Url с помощью Nest ElasticClient - PullRequest
2 голосов
/ 16 мая 2019

Я хочу выполнить агрегацию для поля uri, но вернуть только доменную часть URL-адреса, а не полный URL-адрес. Например, с полем https://stackoverflow.com/questions/ask?guided=true я бы получил stackoverflow.com Учитывая существующий набор данных следующим образом:

"hits" : [
      {
        "_index" : "people",
        "_type" : "_doc",
        "_id" : "L9WewGoBZqCeOmbRIMlV",
        "_score" : 1.0,
        "_source" : {
          "firstName" : "George",
          "lastName" : "Ouma",
          "pageUri" : "http://www.espnfc.com/story/683732/england-football-team-escaped-terrorist-attack-at-1998-world-cup",
          "date" : "2019-05-16T12:29:08.1308177Z"
        }
      },
      {
        "_index" : "people",
        "_type" : "_doc",
        "_id" : "MNWewGoBZqCeOmbRIsma",
        "_score" : 1.0,
        "_source" : {
          "firstName" : "George",
          "lastName" : "Ouma",
          "pageUri" : "http://www.wikipedia.org/wiki/Category:Terrorism_in_Mexico",
          "date" : "2019-05-16T12:29:08.1308803Z"
        }
      },
      {
        "_index" : "people",
        "_type" : "_doc",
        "_id" : "2V-ewGoBiHg_1GebJKIr",
        "_score" : 1.0,
        "_source" : {
          "firstName" : "George",
          "lastName" : "Ouma",
          "pageUri" : "http://www.wikipedia.com/story/683732/england-football-team-escaped-terrorist-attack-at-1998-world-cup",
          "date" : "2019-05-16T12:29:08.1308811Z"
        }
      }
    ]

Мое ведро должно быть следующим:

"buckets" : [
        {
          "key" : "www.espnfc.com",
          "doc_count" : 1
        },
        {
          "key" : "www.wikipedia.com",
          "doc_count" : 2
        }
      ]

У меня есть следующий фрагмент кода о том, как я делаю агрегацию, однако это агрегируется на основе полного URL-адреса, а не доменного имени

var searchResponse = client.Search<Person>(s =>
    s.Size(0)

    .Query(q => q
        .MatchAll()
    )
    .Aggregations(a => a
        .Terms("visited_pages", ta => ta
            .Field(f => f.PageUri.Suffix("keyword"))
        )
    )
);

var aggregations = searchResponse.Aggregations.Terms("visited_pages");

Любая помощь будет с благодарностью:)

Ответы [ 2 ]

1 голос
/ 16 мая 2019

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

Обратите внимание, что, глядя на ваши данные, я пришел к строковой логике.Протестируйте его и измените логику в зависимости от того, что вы ищете.

Лучшим подходом будет попытка создать отдельное поле с именем hostname со значениями того, что вы ищете, и применить к нему агрегирование.

Однако, если вы застряли, я полагаю, что ниже может помочь агрегация !!

Запрос агрегации:

POST <your_index_name>/_search
{
  "size": 0,
  "aggs": {
    "my_unique_urls": {
      "terms": {
        "script" : {
          "inline": """
            String st = doc['pageUri.keyword'].value;
            if(st==null){
              return "";
            } else {
              return st.substring(0, st.lastIndexOf(".")+4);
            }
          """,
          "lang": "painless"
        }
      }
    }
  }
}

Ниже показано, как выглядит мой ответ:

Ответ на запрос:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "my_unique_urls": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "http://www.espnfc.com",
          "doc_count": 1
        },
        {
          "key": "http://www.wikipedia.org",
          "doc_count": 1
        },
        {
          "key": "https://en.wikipedia.org",
          "doc_count": 1
        }
      ]
    }
  }
}

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

1 голос
/ 16 мая 2019

Я бы рекомендовал разбивать эти данные на другое поле (что-то вроде "topleveldomain") во время приема, в противном случае Elasticsearch должен выполнить большую работу для каждого документа, прежде чем он сможет выполнить агрегацию.

...