How to combine results from 2 elasticsearch indexes with different layouts

We have an Elasticsearch with 2 different indexes. In one index there is a field called physical_location which contains a lat en lon subfield. in the other index there is a field called program_run.geolocation with the same nested lat and lon.

Now we want to plot documents from both indexes on a map in our client web application. we tried using a boolean query

{
  "query": {
    "bool": {
      "should": [
        {
          "geo_distance": {
          "distance": "10km",
          "physical_location": {
            "lat": 53.193078596551715,
            "lon": 6.783202751724139
          }
        }
        },
        
        {
          "geo_distance": {
          "distance": "10km",
          "program_run.geolocation": {
            "lat": 53.193078596551715,
            "lon": 6.783202751724139
          }
        }
      } 
        ]
    }
  }
}

but this does give an error, because elastic cant find the first field in the second index and the second field in the first index.

What is the best way of fixing this?

  • Is there a server side way of combining queries for different indexes with different layouts without errors?
  • or is it more handy to combine on the client? (and how to deal with aggregate counts in that case)
  • or is the only way out reindexing and making the names the same in both indexes? (requires lots of refactor work).

how about add alias field type to both index. It may not need reindexing.

This is an example:

PUT /my_locations1
{
  "mappings": {
    "properties": {
      "pin": {
        "properties": {
          "location": {
            "type": "geo_point"
          }
        }
      }
    }
  }
}

PUT /my_locations1/_doc/1
{
  "pin": {
    "location": {
      "lat": 40.12,
      "lon": -71.34
    }
  }
}


PUT /my_locations2
{
  "mappings": {
    "properties": {
      "pin2": {
        "properties": {
          "location": {
            "type": "geo_point"
          }
        }
      }
    }
  }
}

PUT /my_locations2/_doc/1
{
  "pin2": {
    "location": {
      "lat": 40.12,
      "lon": -71.34
    }
  }
}

PUT /my_locations1/_mapping
{
  "properties": {
    "location_for_search": {
      "type":"alias",
      "path": "pin.location"
    }
  }
}

PUT /my_locations2/_mapping
{
  "properties": {
    "location_for_search": {
      "type":"alias",
      "path": "pin2.location"
    }
  }
}

GET /my_locations*/_search
{
  "query":{
    "geo_distance":{
      "distance": "2000km",
      "location_for_search":{
        "lat": 40,
        "lon": -70
      }
    }
  }
}
{
  "took" : 9,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_locations1",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "pin" : {
            "location" : {
              "lat" : 40.12,
              "lon" : -71.34
            }
          }
        }
      },
      {
        "_index" : "my_locations2",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "pin2" : {
            "location" : {
              "lat" : 40.12,
              "lon" : -71.34
            }
          }
        }
      }
    ]
  }
}

3 Likes

Thanks Tomo! This is a real time saver for us!

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.