Elasticsearch - Is it possible to perform a spatial join in a query? - elasticsearch

I would like to perform a spatial join as you would do in PostGIS. So far I have explored the various ways outlined with Geo-shape query, but they only were possible by using a single shape or by accessing a shape in a different index by id like here:
GET /gdelt/_search
{
"query": {
"bool": {
"filter": {
"geo_shape": {
"location": {
"indexed_shape": {
"index": "ne_countries",
"id": "0bnrXnMB0RPtPof-zD-F",
"path": "geometry"
}
}
}
}
}
}
}
Is there a way to spatially join an index with geo_point documents with another or the same index with geo_shape documents?

Related

Aggregate results from several indices in Elasticsearch

I have an Elasticsearch query as shown below.
"query": {
"bool": {
"must": [
{
"match": {
"content": "Netherlands"
}
}
]
}
},
"sort": [
{
"file.created": {
"order": "asc"
}
}
]
}
When I query several indices and sort my results as shown below(in ascending or descending order), my results are in order but of each individual index. So I get trial2 results in order then trial3 results in order.
http://localhost:9200/trial2,trial3/_doc/_search?pretty
What I am looking for, since I am querying several indices and sorting by date, is to get the results of all the indices in ascending or descending order. If a document in trial3 is more recent then the one in trial2, it should appear higher regardless of the order of the indices in the query.
Kindly advice
If you are working with multiple indices that have an equal structure, it would make sense to create an alias that contains all these indices together. You can then run your queries against this virtual big index. Also the sorted results are then in a correct order, while the original index is still referenced in each result document.
POST /_aliases
{
"actions": [
{
"add": {
"index": "trial2",
"alias": "my-alias"
}
},
{
"add": {
"index": "trial3",
"alias": "my-alias"
}
}
]
}

ElasticSearch High Level Rest Client search single field with multiple values

I am using the ElasticSearch high level rest Java client and want to know if it is possible to use the single search API to search for documents matching a single field with multiple values.
For example, I want to search by an id and want to provide multiple ids. Like this:
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery("userId", "123"));
sourceBuilder.query(QueryBuilders.matchQuery("userId", "321"));
What I think is happening is the latest one overrides the previous so I always get the result matching 321 back. Is there a way to do this in a single search or do you have to use the Multi-Search API for these kinds of searches?
I was able to solve this by using bool query. I created an outer MUST with inner SHOULD queries. Here is an example.
{
"query": {
"bool": {
"must": [{
"bool": {
"should": [{
"term": {
"customerId": "123123123"
}
}, {
"term": {
"customerId": "5345345345"
}
}]
}
}, {
"bool": {
"should": [{
"match": {
"location": "japan"
}
}]
}
}]
}
}
}

Elasticsearch returning no geo query results in es6.7

I'm mapping congressional districts in elasticsearch but my efforts are returning no results when trying to query by geoshape even though the query is clearly within the boundary of my WKT values. Here's some relevant data:
The mapping:
"mappings":{
"house":{
"properties":{
"state_name":{
"type":"text"
},
"district":{
"type":"integer"
},
"shape":{
"type":"geo_shape",
"strategy":"recursive"
}
}
}
An example of a WKT on the shape property: POLYGON((-122.612285 37.815224,-122.501272 37.821212,-122.499764 37.819724,-122.41871 37.852491,-122.418673 37.852505,-122.430183 37.918425,-122.432283 37.929824,-122.373982 37.883884,-122.373782 37.883725,-122.28246 37.709309,-122.28178 37.70823,-122.419802 37.708231,-122.420082 37.708231,-122.440893 37.716405,-122.440999 37.716488,-122.428203 37.731851,-122.428038 37.732016,-122.451147 37.731567,-122.453411 37.731568,-122.463399 37.752981,-122.463433 37.753028,-122.469667 37.738505,-122.470597 37.737665,-122.512732 37.735087,-122.578294 37.733988,-122.584728 37.779156,-122.588174 37.789362,-122.612285 37.815224))
My search query in kibana that is clearly inside that WKT:
GET /house/_search
{
"query":{
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"shape": {
"shape": {
"type": "circle",
"coordinates" : [-122.421151, 37.758442],
"radius": "100m"
}
}
}
}
}
}
I've also tried geoshape type point with intersects and contains relation (which is not currently supported).
What else can I do to debug why these documents are not being found?
I realized that my mapping was incorrect. I was manually setting a geo_shape mapping on shape but when my indexes were created they were creating Shape (note capitalization change) properties with type text. Thus none of my indexes had any geo_shape data to search.
The most useful thing I used to debug and find this issue was a readout of the GET /house/mapping data which showed the two distinct properties that should have been a single property.

Using geo_shape filter inside bool filter

I'm trying to combine a geo_shape Elasticsearch filter with a basic term filter within a bool filter, so I can attempt to improve performance of our elasticsearch query, with little success.
This query is used over a set of polygons in Elasticsearch, to determine which shapes the specified point is in.
It seems as though, unless I have the wrong end of the stick, geo_shape filters can't be included inside a bool filter collection like this:
{
"size": 1000,
"fields": [],
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"geo_shape": {
"deliveryAreas.area": {
"shape": {
"coordinates": [
-0.126208,
51.430874
],
"type": "point"
}
}
}
},
{
"term": {
"restaurantState": 3
}
}
]
}
}
}
}
}
The query above runs, but returns 0 results. Using the geo_shape query outside the bool works fine, but the combination of the two seems to fail. I assume it must be a syntax error, as the ElasticSearch docs recommend this approach to make the expensive geo calls cheaper, but no luck so far.

Elastic search multiple terms in a dictionary

I have mapping like:
"profile": {
"properties": {
"educations": {
"properties": {
"university": {
"type": "string"
},
"graduation_year": {
"type": "string"
}
}
}
}
}
which obviously holds the educations history of people. Each person can have multiple educations. What I want to do is search for people who graduated from "SFU" in "2012". To do that I am using filtered search:
"filtered": {
"filter": {
"and": [
{
"term": {
"educations.university": "SFU"
}
},
{
"term": {
"educations.graduation_year": "2012"
}
}
]
}
But what this query does is to find the documents who have "SFU" and "2012" in their education, so this document would match, which is wrong:
educations[0] = {"university": "SFU", "graduation_year": 2000}
educations[1] = {"university": "UBC", "graduation_year": 2012}
Is there anyway I could filter both terms on each education?
You need to define nested type for educations and use nested filter to filter it, or Elasticsearch will internally flattens inner objects into a single object, and return the wrong results.
You can refer here for detail explainations and samples:
http://www.elasticsearch.org/blog/managing-relations-inside-elasticsearch/
http://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-s-children-and-nested-documents/

Resources