Skip to content

Commit 46c1b37

Browse files
authored
fix: properly handle nullable minDistance and maxDistance in near query (#10622)
Fixes #10521
1 parent e4fa171 commit 46c1b37

File tree

3 files changed

+58
-5
lines changed

3 files changed

+58
-5
lines changed

packages/db-mongodb/src/queries/sanitizeQueryValue.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,11 @@ export const sanitizeQueryValue = ({
349349
$geometry: { type: 'Point', coordinates: [parseFloat(lng), parseFloat(lat)] },
350350
}
351351

352-
if (maxDistance) {
352+
if (maxDistance && !Number.isNaN(Number(maxDistance))) {
353353
formattedValue.$maxDistance = parseFloat(maxDistance)
354354
}
355-
if (minDistance) {
355+
356+
if (minDistance && !Number.isNaN(Number(minDistance))) {
356357
formattedValue.$minDistance = parseFloat(minDistance)
357358
}
358359
}

packages/drizzle/src/queries/parseParams.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,12 +319,22 @@ export function parseParams({
319319

320320
case 'near': {
321321
const [lng, lat, maxDistance, minDistance] = queryValue as number[]
322+
const geoConstraints: SQL[] = []
323+
324+
if (typeof maxDistance === 'number' && !Number.isNaN(maxDistance)) {
325+
geoConstraints.push(
326+
sql`ST_DWithin(ST_Transform(${table[columnName]}, 3857), ST_Transform(ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326), 3857), ${maxDistance})`,
327+
)
328+
}
322329

323-
let constraint = sql`ST_DWithin(ST_Transform(${table[columnName]}, 3857), ST_Transform(ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326), 3857), ${maxDistance})`
324330
if (typeof minDistance === 'number' && !Number.isNaN(minDistance)) {
325-
constraint = sql`${constraint} AND ST_Distance(ST_Transform(${table[columnName]}, 3857), ST_Transform(ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326), 3857)) >= ${minDistance}`
331+
geoConstraints.push(
332+
sql`ST_Distance(ST_Transform(${table[columnName]}, 3857), ST_Transform(ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326), 3857)) >= ${minDistance}`,
333+
)
334+
}
335+
if (geoConstraints.length) {
336+
constraints.push(and(...geoConstraints))
326337
}
327-
constraints.push(constraint)
328338
break
329339
}
330340

test/collections-rest/int.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,48 @@ describe('collections-rest', () => {
11281128
expect(resultCount.totalDocs).toBe(1)
11291129
})
11301130

1131+
it('should omit maxDistance and return a document from minDistance', async () => {
1132+
if (payload.db.name === 'sqlite') {
1133+
return
1134+
}
1135+
1136+
const near = `${lat + 0.01}, ${lng + 0.01}, null, 1500`
1137+
const response = await restClient.GET(`/${pointSlug}`, {
1138+
query: {
1139+
where: {
1140+
point: {
1141+
near,
1142+
},
1143+
},
1144+
},
1145+
})
1146+
const result = await response.json()
1147+
1148+
expect(response.status).toEqual(200)
1149+
expect(result.docs).toHaveLength(1)
1150+
})
1151+
1152+
it('should omit maxDistance and not return a document because exceeds minDistance', async () => {
1153+
if (payload.db.name === 'sqlite') {
1154+
return
1155+
}
1156+
1157+
const near = `${lat + 0.01}, ${lng + 0.01}, null, 1700`
1158+
const response = await restClient.GET(`/${pointSlug}`, {
1159+
query: {
1160+
where: {
1161+
point: {
1162+
near,
1163+
},
1164+
},
1165+
},
1166+
})
1167+
const result = await response.json()
1168+
1169+
expect(response.status).toEqual(200)
1170+
expect(result.docs).toHaveLength(0)
1171+
})
1172+
11311173
it('should not return a point far away', async () => {
11321174
if (payload.db.name === 'sqlite') {
11331175
return

0 commit comments

Comments
 (0)