Array types in WFS / WMS and CQL filters

Hi,
I’m not sure whether this is a bug or potential feature “request”, but I’m asking here nonetheless.

I’m using Postgres arrays (integer, text) and when I publish the layer to GeoServer, it is correctly detected, however when I query it via WFS API, it returns Java pointer to the array. It would be nice to convert it to visible representation of an array (like JSON), so instead of:

<wfs:member>
    <a:table_array_test gml:id="table_array_test.4">
        <a:array_column>[Ljava.lang.Integer;@54c50bfa</a:array_column>
        <a:json_column>{"1": 2}</a:json_column>
    </a:table_array_test>
</wfs:member>

would be: <a:array_column>[2, 1, 3]</a:array_column>.

As for the CQL filters, function inArray, that is listed in capabilities, just doesn’t work. Using it like: inArray(3, array_column) just returns an error:

java.lang.ClassCastException: class org.geotools.filter.function.InArrayFunction cannot be cast to class org.geotools.api.filter.Filter (org.geotools.filter.function.InArrayFunction and org.geotools.api.filter.Filter are in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader @4dd8dc3)

class org.geotools.filter.function.InArrayFunction cannot be cast to class org.geotools.api.filter.Filter (org.geotools.filter.function.InArrayFunction and org.geotools.api.filter.Filter are in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader @4dd8dc3)

and using it like so: if_then_else(inArray(4, array_column), 1, 2) = 2 always returns false.
Why are there functions in capabilities and they aren’t documented anywhere in GeoServer documentation? Same goes for jsonArrayContains, which does work better than inArray, still it’s a hassle to use.

Is there any other way to handle array field types, specifically in CQL filters? Proper array functions would be nice. Maybe even use Postgres array functions within CQL filters?

Thanks in advance and best regards.

The GeoMesa PostGIS extension does support binding java.util.List types to Postgres array types, which makes them render better. It also supports inArray predicates through regular equality filters (although this functionality isn’t in a release yet), i.e. myListType = 'bob' matches Array('alice', 'bob'), or I think you can specify matchAction = ALL through WFS/XML predicates to make it an exact match (that works in code at least, I haven’t tried it through WFS).

If anyone is interested in porting the functionality back to the regular PostGIS data store, I’d be happy to provide guidance.

Thanks,

Emilio

I think that your ClassCastException is because inArray is a function, not a predicate, so you would need to do something like inArray(...) = true.

I looked quickly through the GeoMesa extension, it looks very promising. Thanks! We’ll check it out and see if it fits our use-case. If it can do most of the array operations (i.e. ANY, ALL) then it’s great.

Hi, finally found the time to test it. It doesn’t seem to work, at least via WFS (tested via predicates + it still shows Java pointer when fetching records through WFS). I think it’s correctly installed, because console outputs:

2024-11-27 14:37:04 27 Nov 13:37:04 CONFIG [geoserver.wps] - Found 16 bindable processes in GeoMesa Process Factory

I just copied GeoServer Jars (geomesa-gt-gs-plugin_2.13-5.0.1-install.tar.gz) into the WEB-INF/libs directory. I do use regular PostGIS store, because in the GeoMesa docs it’s implied that it works on the regular store as well. Note that I am using latest GeoServer version (2.26.1), so might that be the issue?

I also tested with inArray(...) = true, it returns no records, so something seems broken in the regular inArray function.

I’m not well-versed in Scala and GeoServer/GeoTools core functionality, so I wasn’t able to debug further. Sorry.

Thanks for your help.