fix(db-postgres): sort by distance when the near operator is used (#12185)

Fixes https://github.com/payloadcms/payload/issues/12090, in MongoDB the
documents are sorted by distance automatically whenever the `near`
operation is used, which we have in the docs:
> When querying using the near operator, the returned documents will be
sorted by nearest first.
This fixes this incosistensty between Postgres and MongoDB.

⚠️ This change potentially can cause to produce different results, if
you used the `near` operator without `sort: 'pointFieldName'`.
This commit is contained in:
Sasha
2025-04-22 21:26:13 +03:00
committed by GitHub
parent 2c20051dbf
commit 9955818503
4 changed files with 26 additions and 14 deletions

View File

@@ -3,12 +3,14 @@ import type { FlattenedField, Where } from 'payload'
import type { DrizzleAdapter, GenericColumn } from '../types.js'
import type { BuildQueryJoinAliases } from './buildQuery.js'
import type { QueryContext } from './parseParams.js'
import { parseParams } from './parseParams.js'
export function buildAndOrConditions({
adapter,
aliasTable,
context,
fields,
joins,
locale,
@@ -21,6 +23,7 @@ export function buildAndOrConditions({
adapter: DrizzleAdapter
aliasTable?: Table
collectionSlug?: string
context: QueryContext
fields: FlattenedField[]
globalSlug?: string
joins: BuildQueryJoinAliases
@@ -41,6 +44,7 @@ export function buildAndOrConditions({
const result = parseParams({
adapter,
aliasTable,
context,
fields,
joins,
locale,

View File

@@ -3,6 +3,7 @@ import type { PgTableWithColumns } from 'drizzle-orm/pg-core'
import type { FlattenedField, Sort, Where } from 'payload'
import type { DrizzleAdapter, GenericColumn, GenericTable } from '../types.js'
import type { QueryContext } from './parseParams.js'
import { buildOrderBy } from './buildOrderBy.js'
import { parseParams } from './parseParams.js'
@@ -52,24 +53,14 @@ const buildQuery = function buildQuery({
id: adapter.tables[tableName].id,
}
const orderBy = buildOrderBy({
adapter,
aliasTable,
fields,
joins,
locale,
parentIsLocalized,
selectFields,
sort,
tableName,
})
let where: SQL
const context: QueryContext = { sort }
if (incomingWhere && Object.keys(incomingWhere).length > 0) {
where = parseParams({
adapter,
aliasTable,
context,
fields,
joins,
locale,
@@ -81,6 +72,18 @@ const buildQuery = function buildQuery({
})
}
const orderBy = buildOrderBy({
adapter,
aliasTable,
fields,
joins,
locale,
parentIsLocalized,
selectFields,
sort: context.sort,
tableName,
})
return {
joins,
orderBy,

View File

@@ -1,5 +1,5 @@
import type { SQL, Table } from 'drizzle-orm'
import type { FlattenedField, Operator, Where } from 'payload'
import type { FlattenedField, Operator, Sort, Where } from 'payload'
import { and, isNotNull, isNull, ne, notInArray, or, sql } from 'drizzle-orm'
import { PgUUID } from 'drizzle-orm/pg-core'
@@ -14,9 +14,12 @@ import { buildAndOrConditions } from './buildAndOrConditions.js'
import { getTableColumnFromPath } from './getTableColumnFromPath.js'
import { sanitizeQueryValue } from './sanitizeQueryValue.js'
export type QueryContext = { sort: Sort }
type Args = {
adapter: DrizzleAdapter
aliasTable?: Table
context: QueryContext
fields: FlattenedField[]
joins: BuildQueryJoinAliases
locale?: string
@@ -30,6 +33,7 @@ type Args = {
export function parseParams({
adapter,
aliasTable,
context,
fields,
joins,
locale,
@@ -57,6 +61,7 @@ export function parseParams({
const builtConditions = buildAndOrConditions({
adapter,
aliasTable,
context,
fields,
joins,
locale,
@@ -342,6 +347,7 @@ export function parseParams({
)
}
if (geoConstraints.length) {
context.sort = relationOrPath
constraints.push(and(...geoConstraints))
}
break

View File

@@ -1218,7 +1218,6 @@ describe('collections-rest', () => {
.GET(`/${pointSlug}`, {
query: {
limit: 5,
sort: 'point',
where: {
point: {
// querying large enough range to include all docs