System Information
- Strapi Version: 4.17.1
- Operating System: Docker
- Database: PostGIS
- Node Version: v20.10.0
- NPM Version: 10.2.4
- Yarn Version: N/A
Hi folks!
I’m new in the backend development and I have some concerns about the best way to deal with some of my queries. My application has a filter to search for nearby locations, so for this, I’m using PostGIS to do the query.
I have the collection addresses
and I added a new “find” to the addresses
controller, like I added below. My idea is not to mess with all my find queries, so I check if the query has the filters lat, lon, and distance and do a strapi.db.connection.raw
query.
I found some problems for now, none of them is breaking anything, but I think I can improve it.
Doing this raw query, I lose some of strapi features, like relations. So what I did to fix that is get all the ID from my addresses and use findMany to find all the entities in the collection with this ID and populate with all relations that I need. This worked, but can I do something better?
Another problem is that I lose the pagination. I’m missing something?
And there is another way to do geolocation queries with strapi? I found some comments in this forum and on the stack overflow, but none of them has enough information about how I can create this query/filter.
Some of them use mongodb, others use knex to create the query. I’m open for other ways to do this.
async find(ctx) {
const lon = ctx.query.filters['lon']
const lat = ctx.query.filters['lat']
const distance = ctx.query.filters['distance']
if (lon && lat && distance) {
const req = await strapi.db.connection.raw(`
SELECT id
FROM addresses
WHERE ST_DWithin(ST_SetSRID(ST_MakePoint(lon, lat), 4326)::geography,
ST_MakePoint(${lon}, ${lat})::geography, ${distance})`);
const data = await strapi.entityService.findMany('api::address.address', {
filters: {
id: {
$in: req.rows.map((row) => row.id)
},
},
populate: *
});
return ctx.send({
data,
meta: {}
});
}
const response = await super.find(ctx);
return response;
},
The request from my frontend (using the strapi nuxt module).
find('addresses', {
populate: '*',
filters: {
lat: mapLat.value,
lon: mapLon.value,
distance: distance.value.toFixed(),
}
});