Geopoint search where a document can have multiple locations

I have a need for a full text search that falls outside the current limits of my Couchbase expertise.

Suppose I have a bunch of documents that represent weather stations and they each look like this.

{
  "description": "HONIARA/HENDERSON",
  "docType": "station",
  "geo": [
    {
      "elev": 9,
      "firstTime": 1625097600,
      "lastTime": 1647194400,
      "lat": -9.42,
      "lon": 160.05
    }
  ],
  "id": "MD:V01:METAR:station:AGGH",
  "name": "AGGH",
  "subset": "METAR",
  "type": "MD",
  "updateTime": 1642118411,
  "version": "V01"
}

The reason that the geo field is a list is because weather stations can change location. That is why there is a firstTime and lastTime epoch contained within the geo element. I wanted to be able to know WHEN I knew that a given location was actually valid according to my other data criteria.

Is it possible to create a full text geo search and an associated query such that if given a bounding box it could check for any of the geo elements in the geo list for which the lat/lon are within the bounding box? I would need it to return either the list index or the associated firstTime and lastTime.

Alternatively could I create a query for which I give a bounding box and an epoch and the search would return all the documents which meet the criteria that the epoch falls between the firstTime and lastTime (inclusive) and the associated lat/lon pair is within the bounding box?

Any help on this is greatly appreciated. I searched through the forum and couldn’t find an answer that helped me sufficiently to solve the problem.
thanks

@randy.pierce, let me try answering your questions one at a time …

Is it possible to create a full text geo search and an associated query such that if given a bounding box it could check for any of the geo elements in the geo list for which the lat/lon are within the bounding box? I would need it to return either the list index or the associated firstTime and lastTime.

Couchbase FTS can currently only index a single geo point per field (we are working on extending this to index more points and shapes - which will be available in the near future). That said, if you think you can limit the number of objects within the “geo” field array to one - then yes I believe you will be able to write a bounding box query for it.

You’ll need to index the field “geo” as type:geopoint within your index …

    "geo": {
      "enabled": true,
      "dynamic": false,
      "fields": [
       {
        "index": true,
        "name": "geo",
        "type": "geopoint"
       }
      ]
     }

and this query should retrieve the document you’ve shared …

{"query": {"field": "geo", "top_left": [150, -8], "bottom_right": [170, -10]}}

A Couchbase FTS index flattens out array structures, so it unfortunately will not carry index/position information for an array to let you know the list index or any associated fields. Believe this can be achieved using Couchbase’s SQL-like query language - N1QL.

Alternatively could I create a query for which I give a bounding box and an epoch and the search would return all the documents which meet the criteria that the epoch falls between the firstTime and lastTime (inclusive) and the associated lat/lon pair is within the bounding box?

If that pre-requisite of only a single geo point will be indexed is OK for your use case then yes. You will need to additionally index firstTime and lastTime as type:number within the geo field mapping in your index…

{
  "geo": {
    "dynamic": false,
    "enabled": true,
    "fields": [
      {
        "index": true,
        "name": "geo",
        "type": "geopoint"
      }
    ],
    "properties": {
      "firstTime": {
        "enabled": true,
        "dynamic": false,
        "fields": [
          {
            "index": true,
            "name": "firstTime",
            "type": "number"
          }
        ]
      },
      "lastTime": {
        "enabled": true,
        "dynamic": false,
        "fields": [
          {
            "index": true,
            "name": "lastTime",
            "type": "number"
          }
        ]
      }
    }
  }
}

And a conjunction query like this should be able fetch you your matches …

{
  "query": {
    "conjuncts": [
      {"field": "geo", "top_left": [150, -8], "bottom_right": [170, -10]},
      {"field": "geo.firstTime", "max": 1640000000},
      {"field": "geo.lastTime", "min": 1640000000}
    ]
  }
}

Hope this was helpful.

Thank you!
That actually does help quite a lot.
Do you by any chance have an estimate of when “…which will be available in the near future” will be?

Do you by any chance have an estimate of when “…which will be available in the near future” will be?

At this point, we’re looking at the end of summer.