1

I'm using the following GetFeature POST request (to http://localhost:8080/geoserver/wfs) trying to query the sample "bugsites" layer that ships with GeoServer. The request is supposed to return the features whose cat attribute is contained in the given set of literals:

<?xml version="1.0"?>
<wfs:GetFeature
    xmlns:wfs="http://www.opengis.net/wfs/2.0"
    xmlns:fes="http://www.opengis.net/fes/2.0"
    outputFormat="application/json"
>
    <wfs:Query typeNames="sf:bugsites">
        <fes:Filter>
            <fes:PropertyIsEqualTo>
                <fes:ValueReference>cat</fes:ValueReference>
                <fes:Function name="in">
                    <fes:Literal>19</fes:Literal>
                    <fes:Literal>20</fes:Literal>
                    <fes:Literal>21</fes:Literal>
                </fes:Function>
            </fes:PropertyIsEqualTo>
        </fes:Filter>
    </wfs:Query>
</wfs:GetFeature>

However, no features are being returned:

{
    "type": "FeatureCollection",
    "features": [],
    "totalFeatures": 0,
    "numberMatched": 0,
    "numberReturned": 0,
    "timeStamp": "2024-02-29T08:57:26.888Z",
    "crs": null
}

When using a GET request along with the Common Query Language (CQL) on the other hand ...

http://localhost:8080/geoserver/wfs
    ?service=WFS
    &version=2.0.0
    &request=GetFeature
    &typeNames=sf:bugsites
    &outputFormat=application/json
    &cql_filter=cat%20IN%20(19,20,21)

(clickable link)

..., I do get the three features returned:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "id": "bugsites.19",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    591224,
                    4919553
                ]
            },
            "geometry_name": "the_geom",
            "properties": {
                "cat": 19,
                "str1": "Beetle site"
            }
        },
        {
            "type": "Feature",
            "id": "bugsites.20",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    591306,
                    4920512
                ]
            },
            "geometry_name": "the_geom",
            "properties": {
                "cat": 20,
                "str1": "Beetle site"
            }
        },
        {
            "type": "Feature",
            "id": "bugsites.21",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    591339,
                    4915303
                ]
            },
            "geometry_name": "the_geom",
            "properties": {
                "cat": 21,
                "str1": "Beetle site"
            }
        }
    ],
    "totalFeatures": 3,
    "numberMatched": 3,
    "numberReturned": 3,
    "timeStamp": "2024-02-29T09:06:13.801Z",
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:EPSG::26713"
        }
    }
}

Ideally, I'd like to use POST requests (for one, because the list of literals in the actual request might get quite large).

What is wrong with the first request?

EDIT:

It seems like the filters are being converted differently. Here's what I'm getting for the first (the POST) request in the geoserver.log file:

29 Feb 10:39:36 INFO   [geoserver.wfs] - 
Request: getFeature
    service = WFS
    version = 2.0.0
    baseUrl = http://localhost:8080/geoserver/
    outputFormat = application/json
    resolve = none
    resolveDepth = *
    resolveTimeout = 300
    resultType = results
    abstractQueryExpressionGroup[0] = wfs:abstractQueryExpression=net.opengis.wfs20.impl.QueryTypeImpl@1cc3c1a3 (handle: null) (abstractProjectionClause: null, abstractSelectionClause: [ cat = in([19], [20], [21]) ], abstractSortingClause: null, aliases: null, typeNames: [{http://www.openplans.org/spearfish}bugsites]) (featureVersion: null, srsName: null, filter: null, propertyNames: null, sortBy: null)
    abstractQueryExpression[0]:
        abstractSelectionClause = [ cat = in([19], [20], [21]) ]
        typeNames[0] = {http://www.openplans.org/spearfish}bugsites
        filter = [ cat = in([19], [20], [21]) ]
29 Feb 10:39:36 INFO   [wfs.json] - about to encode JSON

For the second (the GET) request, the following information is written:

29 Feb 10:39:52 INFO   [geoserver.wfs] - 
Request: getFeature
    service = WFS
    version = 2.0.0
    baseUrl = http://localhost:8080/geoserver/
    outputFormat = application/json
    resolve = none
    resolveDepth = *
    resolveTimeout = 300
    resultType = results
    abstractQueryExpressionGroup[0] = wfs:abstractQueryExpression=net.opengis.wfs20.impl.QueryTypeImpl@172d6f57 (handle: null) (abstractProjectionClause: null, abstractSelectionClause: [[ cat = 20 ] OR [ cat = 21 ]], abstractSortingClause: null, aliases: null, typeNames: [{http://www.openplans.org/spearfish}bugsites]) (featureVersion: null, srsName: null, filter: null, propertyNames: null, sortBy: null)
    abstractQueryExpression[0]:
        abstractSelectionClause = [[ cat = 20 ] OR [ cat = 21 ]]
        typeNames[0] = {http://www.openplans.org/spearfish}bugsites
        filter = [[ cat = 20 ] OR [ cat = 21 ]]
29 Feb 10:39:52 INFO   [wfs.json] - about to encode JSON

The POST request seems to try to match against single-element arrays.

But how would I use it correctly?

1 Answer 1

0

I could not figure out how to use the in function in a POST request properly.

To filter for a predefined set of values, one may stick to using a simple OR filter:

<?xml version="1.0"?>
<wfs:GetFeature
    xmlns:wfs="http://www.opengis.net/wfs/2.0"
    xmlns:fes="http://www.opengis.net/fes/2.0"
    outputFormat="application/json"
>
    <wfs:Query typeNames="sf:bugsites">
        <fes:Filter>
            <fes:Or>
                <fes:PropertyIsEqualTo>
                    <fes:ValueReference>cat</fes:ValueReference>
                    <fes:Literal>19</fes:Literal>
                </fes:PropertyIsEqualTo>
                <fes:PropertyIsEqualTo>
                    <fes:ValueReference>cat</fes:ValueReference>
                    <fes:Literal>20</fes:Literal>
                </fes:PropertyIsEqualTo>
                <fes:PropertyIsEqualTo>
                    <fes:ValueReference>cat</fes:ValueReference>
                    <fes:Literal>21</fes:Literal>
                </fes:PropertyIsEqualTo>
            </fes:Or>
        </fes:Filter>
    </wfs:Query>
</wfs:GetFeature>

The request may be simplified when trying to filter for feature/resource IDs:

<?xml version="1.0"?>
<wfs:GetFeature
    xmlns:wfs="http://www.opengis.net/wfs/2.0"
    xmlns:fes="http://www.opengis.net/fes/2.0"
    outputFormat="application/json"
>
    <wfs:Query typeNames="sf:bugsites">
        <fes:Filter>
            <fes:Or>
                <fes:ResourceId rid="bugsites.19"/>
                <fes:ResourceId rid="bugsites.20"/>
                <fes:ResourceId rid="bugsites.21"/>
            </fes:Or>
        </fes:Filter>
    </wfs:Query>
</wfs:GetFeature>

The suggested way of using the in function ...

<?xml version="1.0"?>
<wfs:GetFeature
    xmlns:wfs="http://www.opengis.net/wfs/2.0"
    xmlns:fes="http://www.opengis.net/fes/2.0"
    outputFormat="application/json"
>
    <wfs:Query typeNames="sf:bugsites">
        <fes:Filter>
            <fes:Function name="in">
                <fes:ValueReference>cat</fes:ValueReference>
                <fes:Literal>19</fes:Literal>
                <fes:Literal>20</fes:Literal>
                <fes:Literal>21</fes:Literal>
            </fes:Function>
        </fes:Filter>
    </wfs:Query>
</wfs:GetFeature>

... does not seem to work with GeoServer ...

<?xml version="1.0" encoding="UTF-8"?>
<ows:ExceptionReport xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.0" xsi:schemaLocation="http://www.opengis.net/ows/1.1 http://localhost:8080/geoserver/schemas/ows/1.1.0/owsAll.xsd">
    <ows:Exception exceptionCode="OperationParsingFailed">
        <ows:ExceptionText>Request parsing failed
Parsing failed for Filter: java.lang.RuntimeException: Unable to find function 
Unable to find function </ows:ExceptionText>
    </ows:Exception>
</ows:ExceptionReport>

... even though the function is returned as part of the GetCapabilities request:

<fes:Function name="in">
    <fes:Returns>xs:boolean</fes:Returns>
    <fes:Arguments>
        <fes:Argument name="candidate">
            <fes:Type>xs:string</fes:Type>
        </fes:Argument>
        <fes:Argument name="v">
            <fes:Type>xs:string</fes:Type>
        </fes:Argument>
    </fes:Arguments>
</fes:Function>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.