2017-09-12 1 views
0

J'ai eu du mal à comprendre cela. J'ai des enregistrements avec l'heure et le GPS en tant que tel:ElasticSearch Aggregate Intersection de GPS

{ID: 1,Time:"2017-01-1",gps:{lat:38.00,lon:-79.00}}, 
{ID: 2,Time:"2017-01-1",gps:{lat:38.00,lon:-79.00}}, 
{ID: 1,Time:"2017-01-2",gps:{lat:39.00,lon:-77.00}}, 
{ID: 2,Time:"2017-01-2",gps:{lat:20.00,lon:-20.00}}, 
{ID: 1,Time:"2017-01-3",gps:{lat:20.00,lon:-20.00}}, 
{ID: 3,Time:"2017-01-1",gps:{lat:20.00,lon:-20.00}}, 
.......... 

J'ai une carte qui permet de dessiner des cercles et de sélectionner des régions. Actuellement, je peux facilement interroger et agréger les enregistrements qui sont apparus dans N'IMPORTE QUEL des emplacements sélectionnés. Ceci est un exemple:

{ 
    "query": { 
    "bool": { 
     "should": [ 
     { 
      "geo_distance": { 
      "distance": 56100.0, 
      "gps": { 
       "lat": 38, 
       "lon": -79 
      } 
      } 
     }, 
     { 
      "geo_distance": { 
      "distance": 56100.0, 
      "gps": { 
       "lat": 39, 
       "lon": -77 
      } 
      } 
     } 
     ] 
    } 
    }, 
    "aggs": { 
    "by_record_id":{ 
     "terms": { 
     "field": "id" 
     } 
    } 
    } 
} 

Cependant, je suis un peu déconcerté sur comment obtenir l'intersection des sélections. (NOTE: les cercles ne se chevauchent pas). Essentiellement, je veux un agrégat des enregistrements qui ont eu des valeurs gps qui sont apparues dans les deux cercles et supprimer ceux qui ont seulement apparu dans un ou aucun. Par exemple, avec les enregistrements ci-dessus, je voudrais seulement un résultat d'agrégation pour ID = 1 (comme ID = 2 et ID = 3 n'apparaissent pas dans les deux cercles).

Si je change la requête en {"query": {"bool": {"must": [...]}}}, je n'obtiens aucun résultat. Parce que, évidemment, aucun enregistrement n'apparaît dans deux endroits en même temps.

J'ai essayé beaucoup de choses différentes avec des requêtes dont function_score (en plaçant chaque emplacement dans les fonctions) et en utilisant les scores (basés sur différents types de score). De plus, j'ai essayé de nombreuses combinaisons d'agrégats, y compris le filtrage avec top_hits, cardinality (avec precision_threshold), bucket_selector avec cardinality.

Cela semble super facile et évident en SQL. S'il vous plaît, aidez un nube élastique.

+0

J'ai fait une note à ce sujet dans l'écriture. Utiliser 'must' ne fonctionne pas. Il ne renvoie aucun résultat. – Andrew

+0

ohhh je vois maintenant. je pense que vous pouvez utiliser le sélecteur de seau pipline agrégation vous pouvez le voir [ici] (https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-selector-aggregation .html). la syntaxe est un peu brouillon mais il fera le travail – tomas

+0

serait-il trop demander un meilleur exemple que celui fourni par le lien elasticsearch? dois-je créer des filtres/termes séparés (ex: filtre sur un emplacement/agrégat sur l'ID)? donc dans mon cas, j'aurais loc1 et loc2? puis utilisez un bucket_selector pour calculer l'intersection? comment pourrais-je faire fonctionner le script? – Andrew

Répondre

0

Vous avez la réponse!

"aggs": { 
    "ids": { 
    "terms": { 
     "field": "ID" 
    }, 
    "aggs": { 
    "the_filter": { 
     "bucket_selector": { 
     "buckets_path": { 
      "the_doc_count": "_count" 
     }, 
     "script": "params.the_doc_count >= 2" 
     } 
     } 
    } 
    } 
} 
+0

J'ai essayé, mais je ne suis pas sûr que la section de script fonctionnera. Plus précisément, recherchez _count> = 2. Il semble que cela pourrait fonctionner si un enregistrement n'apparaît dans une plage qu'une seule fois. Mais au fil du temps, l'enregistrement peut apparaître dans la même plage plusieurs fois. C'est comme si j'avais besoin de seau de chemin vers les résultats de chaque emplacement, puis effectuer une sorte d'union/intersection à partir de là? – Andrew

+0

Je pense que vous devez changer la façon dont vous indexez vos données pour résoudre ce problème – tomas