From 245a2dee7e80519ff205faaaf538607b2a03b309 Mon Sep 17 00:00:00 2001 From: Sasha <64744993+r1tsuu@users.noreply.github.com> Date: Fri, 13 Jun 2025 17:11:13 +0300 Subject: [PATCH] fix(db-mongodb): 4x and more level deep relationships querying (#12800) Fixes https://github.com/payloadcms/payload/issues/12721 --- .../src/queries/buildSearchParams.ts | 11 +++++--- test/relationships/config.ts | 5 ++++ test/relationships/int.spec.ts | 28 ++++++++++++++++++- test/relationships/payload-types.ts | 2 ++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/packages/db-mongodb/src/queries/buildSearchParams.ts b/packages/db-mongodb/src/queries/buildSearchParams.ts index d32fdf60f0..c33046c8e3 100644 --- a/packages/db-mongodb/src/queries/buildSearchParams.ts +++ b/packages/db-mongodb/src/queries/buildSearchParams.ts @@ -245,10 +245,13 @@ export async function buildSearchParam({ value: { $in }, } } else { - relationshipQuery = { - value: { - _id: { $in }, - }, + const nextSubPath = pathsToQuery[i + 1]?.path + if (nextSubPath) { + relationshipQuery = { + value: { + [nextSubPath]: { $in }, + }, + } } } } diff --git a/test/relationships/config.ts b/test/relationships/config.ts index 4fe5c397f8..593ead8d41 100644 --- a/test/relationships/config.ts +++ b/test/relationships/config.ts @@ -254,6 +254,11 @@ export default buildConfigWithDefaults({ relationTo: 'movies', hasMany: true, }, + { + name: 'movie', + type: 'relationship', + relationTo: 'movies', + }, { name: 'directors', type: 'relationship', diff --git a/test/relationships/int.spec.ts b/test/relationships/int.spec.ts index d8deded0a3..db932b5070 100644 --- a/test/relationships/int.spec.ts +++ b/test/relationships/int.spec.ts @@ -17,7 +17,6 @@ import type { } from './payload-types.js' import { initPayloadInt } from '../helpers/initPayloadInt.js' -import { isMongoose } from '../helpers/isMongoose.js' import { chainedRelSlug, customIdNumberSlug, @@ -430,6 +429,33 @@ describe('Relationships', () => { expect(result.docs[0].id).toBe(id) }) + it('should allow 4x deep querying', async () => { + const movie_1 = await payload.create({ + collection: 'movies', + data: { name: 'random_movie_1' }, + }) + const director_1 = await payload.create({ + collection: 'directors', + data: { name: 'random_director_1', movie: movie_1.id }, + }) + const movie_2 = await payload.create({ + collection: 'movies', + data: { name: 'random_movie_2', director: director_1.id }, + }) + const director_2 = await payload.create({ + collection: 'directors', + data: { name: 'random_director_2', movie: movie_2.id }, + }) + + const res = await payload.find({ + collection: 'directors', + where: { 'movie.director.movie.name': { equals: 'random_movie_1' } }, + }) + + expect(res.totalDocs).toBe(1) + expect(res.docs[0].id).toBe(director_2.id) + }) + describe('hasMany relationships', () => { it('should retrieve totalDocs correctly with hasMany,', async () => { const movie1 = await payload.create({ diff --git a/test/relationships/payload-types.ts b/test/relationships/payload-types.ts index cea19dae4e..08eb99bc18 100644 --- a/test/relationships/payload-types.ts +++ b/test/relationships/payload-types.ts @@ -280,6 +280,7 @@ export interface Director { name?: string | null; localized?: string | null; movies?: (string | Movie)[] | null; + movie?: (string | null) | Movie; directors?: (string | Director)[] | null; updatedAt: string; createdAt: string; @@ -742,6 +743,7 @@ export interface DirectorsSelect { name?: T; localized?: T; movies?: T; + movie?: T; directors?: T; updatedAt?: T; createdAt?: T;