Книга: Apache Solr Search Patterns
Назад: Indexing for spatial search
Дальше: Distance sort and relevancy boost

Searching and filtering on a spatial index

Spatial fields in a Solr index can be searched and filtered using the {!geofilt} and {!bbox} query filters. These filters were introduced and are available in Solr 4.2 onward. We saw a working example of geofilt earlier in this chapter. Let us go through some other queries that can be executed on a spatial index in Solr.

The bbox query

The working of a bbox filter is similar to that of geofilt, except that the former uses the bounding box of a calculated circle. The query remains the same, except that we use the {!bbox} filter instead of the {!geofilt} filter. To convert the earlier query to bbox from geofilt, we run the following query:

http://localhost:8983/solr/collection1/select/?q=*:*&fq={!bbox pt=28.643059,77.368885 sfield=store d=10}

The output in our case would remain the same as that in the figure – Stores within 10 km from our location point – shown earlier in this chapter, but the search now includes the grayed-out area, as shown in the following image. If there were any store locations in the grayed-out area, the earlier search using the {!geofilt} filter would not return them in the result, while the {!bbox} filter would do so.

The following figure shows the area covered by the bbox query:

The bbox query

In order to understand the execution of the query, let us index the default documents available with Solr into our index. In the exampledocs folder, run the following command:

 java -jar post.jar *.xml 

This will index the default documents in Solr that carry the store locations. Now execute the following query:

http://localhost:8983/solr/collection1/select/?fl=name,store&q=*:*&fq ={!geofilt}&sfield=store&pt=45.15,-93.85&d=5

This will give out 3 stores that are within 5 km of the point 45.15,-93.85.

The execution of the previous query in Solr yields the following output:

The bbox query

Here we are using the geofilt filter. If we convert this to the bbox filter, we will be getting five store locations in our output. The Solr query would be:

http://localhost:8983/solr/collection1/select/?fl=store&q=*:*&fq={!bb ox}&sfield=store&pt=45.15,-93.85&d=5

The output will be as shown in the following figure:

The bbox query

Since this search is executed within the bounding box of a circle, the area thus covered is always a square. Therefore, the bbox filter cannot be used to search a rectangle. To search a rectangle, we can use the following range query:

http://localhost:8983/solr/collection1/select/?fl=store&q=*:*&fq=stor e:[45.15,-93.9 TO 45.2,-93.88] 

This search ranges from the lower left point at 45.15,-93.9 to the top right point at 45.2,-93.88 forming a rectangle. The query in the following image shows the results of this search:

The bbox query

Note

Filters such as geofilt, bbox, and geodist use certain spatial search–specific parameters.

These parameters are as follows:

d: It denotes the distance and is measured in kilometers.

pt: It represents a specific point in the latitude / longitude coordinate format.

sfield: It specifies a spatial field and is of location field type by default.

An unconventional Solr query parser known as the field-query style approach has been introduced in Solr 4.0. This syntax is used for a spatial predicate that excludes Intersects, or to use WKT formatted shapes (for example, a polygon), or to add some precision tuning options. Let us see some examples:

fq=store:"Intersects(28 77 29 78)"

The complete query will be:

http://localhost:8983/solr/collection1/select/?q=*:*&fq=store:"Inters ects(28 77 29 78)"

This query looks for any store that intersects the rectangle formed by the specified coordinates. We can see that the rectangle with the ID CXXX1 is the output of our query, as shown in the following image:

The bbox query

Suppose that we are located at the location specified by (28.642815,77.368413) and we want to inspect a circle having a radius of 20 km with reference to our location, for any store that intersects this circle.

First, we will have to convert 20 km into degrees using the formula introduced in the previous section:

Degree d = 20 / 111.1951          = 0.1798

Now our query using the Intersects predicate will be:

http://localhost:8983/solr/collection1/select/?q=*:*&fq=store:"Inters ects(Circle(28.642815,77.368413 d=0.1798))"&fl=store,name

We can see that the result indicates three stores. Also, the circle that we indexed earlier intersects the circle specified in the query.

The following image shows the output obtained from the execution of the previous query:

The bbox query

Now let us see an example of the IsWithin predicate:

fq=store:"IsWithin(POLYGON((19 49, 17 61, 25 70, 27 62, 31 55, 19 49))) distErrPct=0"

We are trying to determine whether there is anything in the polygon specified earlier for which the Solr query will be:

http://localhost:8983/solr/collection1/select/?q=*:*&fq=store:"IsWith in(POLYGON((19 49, 17 61, 25 70, 27 62, 31 55, 19 49))) distErrPct=0"&fl=store,name

The result from our query shows the polygon that we had indexed earlier.

The output from the previous query is shown in the following image:

The bbox query

This example shows the implementation of WKT with a tuning option. The spatial chunk of the query is placed as a subquery in the full Solr query that resembles a Lucene phrase query. The query starts with spatial predicates such as Intersects and IsWithin followed by either WKT or some other shape format that is enclosed in parentheses.

The distErrPct class defines the precision option for the query shape. Its default value is 0.025 (2.5%). We have set distErrPct as 0, which makes the query shape as accurate as that of a grid. We may also specify the distErr option if we want to explicitly set the precision for the shape for which we know the accuracy in exact terms instead of the relative terms.

Solr 4.3 introduces additional predicates such as isWithin, Contains, and isDisjointTo. The predicates Intersects or isDisjointTo work fine for only indexed points. Also, isWithin and Contains predicates are useful for searching indexed non-point shapes. In addition, isWithin is used to search for indexed shapes that are within the query shape, while Contains searches for indexed shapes that contain the query shape.

Назад: Indexing for spatial search
Дальше: Distance sort and relevancy boost

Solr
Testing
dosare
121