Elasticsearch - запрос для определения всех уникальных идентификаторов, которые находятся на расстоянии X от определенного идентификатора? - PullRequest
1 голос
/ 26 апреля 2020

У меня есть данные в этом формате, сгенерированные из случайного блуждания (для имитации ходящих людей). Это настраивается следующим образом: {location: {lat: someLat, lon: someLong}, id: uniqueId, date: date}. Я пытаюсь написать запрос по уникальному идентификатору пользователя и определить, сколько других уникальных идентификаторов появилось на расстоянии X от заданного идентификатора за определенный промежуток времени. Любые советы о том, как это сделать?

Моя идея состоит в том, чтобы иметь агрегацию фильтра верхнего уровня с вложенным гео-запросом. Я думаю, что запрос географического расстояния - это путь к go, но я не уверен, как включить его в следующий запрос, чтобы получить все уникальные идентификаторы, которые находятся на расстоянии X от идентификатора, по которому я фильтрую. Приведенный ниже запрос - это то, с чего я начинаю, я отфильтровываю все документы с этого момента - 1 день до настоящего времени, где идентификатором пользователя документов является предоставленное значение. Как бы я проверил все другие документы на предмет их расстояния по отношению к документам, которые соответствуют этому запросу?

{
    "aggs" : {
        "range": {
            "date_range": {
                "field": "date",
                "format": "MM-yyyy",
                "ranges": [
                    { "to": "now" }, 
                    { "from": "now-1d" } 
                ]
            }
        },
        "locations" : {
            "filter" : { 
              "term": { "id.keyword": "7a50ab18-886b-42a2-80ad-3d45112e3cfd" }
            }
        }
    }
}

1 Ответ

1 голос
/ 26 апреля 2020

Ваша догадка верна. Все это можно сделать с помощью фильтрации range & geo_distance и сортировки _geo_distance. Вы хотите фильтровать на уровне запроса, а не в аггс:

GET walking/_search
{
  "size": 0, 
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "date": {
              "gte": "now-1d"
            }
          }
        }
      ],
      "filter": [
        {
          "geo_distance": {
            "distance": "20m",
            "location": {
              "lat": 48.20150179951008,
              "lon": 16.39111876487732
            }
          }
        }
      ]
    }
  },
  "aggs": {
     "rings_around_loc": {
          "geo_distance": {
            "field": "location",
            "origin": {
              "lat": 48.20150179951008,
              "lon": 16.39111876487732
            },
            "unit": "m",
            "keyed": true,
            "ranges": [
              {
                "to": 10
              },
              {
                "from": 10,
                "to": 50
              },
              {
                "from": 50
              }
            ]
          }
    },
    "locations": {
      "value_count": {
        "field": "id.keyword"
      }
    }
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 48.20150179951008,
          "lon": 16.39111876487732
        },
        "order": "asc",
        "unit": "m",
        "mode": "min",
        "distance_type": "arc",
        "ignore_unmapped": true
      }
    }
  ]
}

Не уверены, для чего вам нужны диапазоны диапазонов, поэтому я их пропустил.


Полные шаги для репликации:

PUT walking
{
  "mappings": {
    "properties": {
      "date": {
        "type": "date"
      },
      "id": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      },
      "location": {
        "type": "geo_point"
      }
    }
  }
}

А затем POST _bulk это данные случайного блуждания

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...