Geo-distance aggregations not returning anything


#1

Enonic version: 6.15.0 and 6.12.0
OS: Docker setup and Mac

Cannot get geo-distance aggregations to work in our docker environment.
Also tried running locally following https://xp.readthedocs.io/en/6.15/index.html, but still no results.

I tested with a simple part that just logges the query. This uses the example found on https://xp.readthedocs.io/en/stable/developer/search/aggregations/geo-distance.html

var contentLib = require("/lib/xp/content"); // Import the content function library

exports.get = function(req) {
    var articles = contentLib.query({
        query: "",
        start: 0,
        count: 100,
        contentTypes: [app.name + ":article"],
        sort: "geoDistance('data.mylocation', '90.0,0.0') ASC",
        aggregations: {
            distance: {
                geo_distance: {
                    field: "data.mylocation",
                    unit: "km",
                    origin: {
                        lat: "90.0",
                        lon: "0.0"
                    },
                    ranges: [
                        { from: 0, to: 1200 },
                        { from: 1200, to: 4000 },
                        { from: 4000, to: 12000 },
                        { from: 12000 }
                    ]
                }
            }
        }
    });
    log.info(JSON.stringify(articles, null, 2));
    return {
        body: "<div></div>",
        contentType: "text/html"
    };
};

I made two instance of this simple content type:

<content-type>
    <display-name>Artikkel</display-name>
    <super-type>base:structured</super-type>
    <form>
        <input name="mylocation" type="GeoPoint">
          <label>Lokasjon</label>
          <occurrences minimum="0" maximum="1"/>
        </input>
    </form>
</content-type>

The result is show in the JSON.
It finds the two articles, it shows them having a data.mylocation field that matches the one in the aggregation.
But still the it returns empty, “aggregations”: {}.
The inputted ranges should create at least one bucket, but none are returned.
{
“total”: 2,
“count”: 2,
“hits”: [
{
“_id”: “e206d077-65c4-402e-8564-3819acf7584e”,
“_name”: “test1”,
“_path”: “/site/articles/test1”,
“creator”: “user:system:ole.saggau”,
“modifier”: “user:system:ole.saggau”,
“createdTime”: “2018-08-30T07:38:28.765Z”,
“modifiedTime”: “2018-08-30T07:39:21.213Z”,
“owner”: “user:system:ole.saggau”,
“type”: “com.company.myapp:article”,
“displayName”: “test1”,
“hasChildren”: false,
“valid”: true,
“data”: {
“mylocation”: “89.0,1.0”
},
“x”: {},
“page”: {},
“attachments”: {},
“publish”: {}
},
{
“_id”: “918552cd-38c0-45ec-9a0e-3d676ac25a33”,
“_name”: “test2”,
“_path”: “/site/articles/test2”,
“creator”: “user:system:ole.saggau”,
“modifier”: “user:system:ole.saggau”,
“createdTime”: “2018-08-30T07:39:28.792Z”,
“modifiedTime”: “2018-08-30T07:39:42.981Z”,
“owner”: “user:system:ole.saggau”,
“type”: “com.company.myapp:article”,
“displayName”: “test2”,
“hasChildren”: false,
“valid”: true,
“data”: {
“mylocation”: “20.0,10.0”
},
“x”: {},
“page”: {},
“attachments”: {},
“publish”: {}
}
],
“aggregations”: {}
}

Is this intended behaviour? I have tried adding other fields and aggregations and they work, but I cannot get geo-distance to work.


#2

It is “geoDistance” and not “geo_distance”.
This was an Enonic XP 6.0 modification but the documentation was apparently not correctly updated.
We will fix the documentation.


#3

Using geoDistance seems to work with the example, but I get the error in my own code:
java.lang.Double cannot be cast to java.lang.Integer
I have narrowed this down to my ranges:
ranges: [
{ from: 0, to: parseInt(params.distance) },
{ from: parseInt(params.distance), to: 10000 }
]
Not using parseInt gives me:
java.lang.String cannot be cast to java.lang.Integer

I think this is because JavaScript Number type is equivalent to the Java Double type, as these threads seem to imply:



Hardcoding a number like 10 works without flaw, but I cannot get a dynamic value to work. Any advice?


#4

perhaps try Number() instead of parseInt() ?


#5

Using Number() returns the same error, java.lang.Double cannot be cast to java.lang.Integer

My current workaround now is a ridiculous hack which somehow works, populating a list with number 0-100 and using the parseInt(value) as the index.

var hacky = Array.apply(null, { length: 100 }).map(Number.call, Number);
....
{ from: hacky[parseInt(params.distance)], to 10000 }

#6

This second problem is a bug. We will create a fix for the next version (and also allow to specify float/double values).

Meanwhile if it is blocking you, you could use Java.type('java.lang.Integer').parseInt(params.distance) instead of parseInt(params.distance)