Is it possible to issue a spatial join with shapes from two tables?

173 views Asked by At

I want to be able to run a query like:

select A.*
  from A
  join B
    on match(A.geom,B.wkt) using within;

But i get:

ERROR:  UnhandledServerException: java.lang.IllegalArgumentException: queryTerm must be a literal

Sample schema:

create table if not exists A (
  id integer,
  geom geo_shape
);

create table if not exists B (
  id integer,
  wkt string index off
);

The reason for trying wkt string is due to the documentation's use of WKT literals. Additionally, since our actual implementation is a variable number of geometries that we might join against and geo_shape can't exist in an object, we were hoping to WKT would work with a join.

Update 1 (per Augmented Jacob's answer) Trying geo_shape join geo_shape with this schema:

create table if not exists B (
  id integer,
  wkt geo_shape
);

And the above query produces a different error:

SQLParseException: Couldn't create executionContexts from NodeOperations
... original-error: Can't handle Symbol io.crate.analyze.symbol.MatchPredicate@6666c921 

And, while the error isn't ideal, I wouldn't expect it to work anyway since the docs state:

Note

One MATCH predicate cannot combine columns of both relations of a join.

Update 2 With geo_shape join geo_shape, match doesn't work but within works, though, being "exact" queries, the performance makes it mostly unusable, at least across our 2.4B rows.

select A.*
  from A
  join B
    on within(B.wkt,A.geom);
2

There are 2 answers

0
Michael Beer On BEST ANSWER

If you are using the match predicate Crate leverages the generated Lucene index of the geo_shape to get really fast but not "exact" results (as you already noticed). However, a geospatial match on two relations (join) is not possible with Lucene and that is why Crate is not able to do it. The documentation explains it also here:
https://crate.io/docs/reference/en/latest/sql/joins.html#join-conditions

1
Augmented Jacob On

Your Variable in Table A geom is of type geo_shape whereas B has wkt of type string.

Change them to matching types and it should solve your java.lang.IllegalArgumentException