Запрос Prisma 2 для возврата только тех записей, которые связаны со ВСЕМИ предоставленными идентификаторами тегов
У меня есть таблицы Principles и Tags. И между ними существует связь "многие ко многим" (неявно соединенные).
Без использования prisma.raw
, как я могу выполнить следующий запрос?
SELECT p.id, p.title, p.description, p.createdAt, p.modifiedAt
FROM principle p
WHERE EXISTS (SELECT NULL
FROM _PrincipleToTag pt
WHERE pt.B IN (${tagIds.join(',')})
AND pt.A = p.id
GROUP BY pt.A
HAVING COUNT(DISTINCT pt.B) = ${tagIds.length})
Как я могу обновить этот запрос Prisma 2, чтобы возвращаемые принципы были только принципами, которые связаны со ВСЕМИ предоставленными идентификаторами тегов?
export const principles = ({ tagIds }) => {
const payload = {
where: {
//TODO filter based on tagIds
},
}
return db.principle.findMany(payload)
}
В документах упоминаетсяcontains
а также in
а также every
, но я не могу найти примеры того, что пытаюсь сделать.
Я использую RedwoodJs, Prisma 2, Apollo, GraphQL.
Обновление в ответ на комментарий: вот SDL:
input CreatePrincipleInput {
title: String!
description: String
}
input CreatePrincipleWithTagsInput {
title: String!
description: String
tagIdsJson: String
}
input CreateTagInput {
title: String!
description: String
}
# A date string, such as 2007-12-03, compliant with the `full-date` format
# outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for
# representation of dates and times using the Gregorian calendar.
scalar Date
# A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the
# `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO
# 8601 standard for representation of dates and times using the Gregorian calendar.
scalar DateTime
type Mutation {
createPrinciple(input: CreatePrincipleInput!): Principle
createPrincipleWithTags(input: CreatePrincipleWithTagsInput!): Principle
updatePrinciple(id: Int!, input: UpdatePrincipleInput!): Principle!
deletePrinciple(id: Int!): Principle!
createTag(input: CreateTagInput!): Tag!
updateTag(id: Int!, input: UpdateTagInput!): Tag!
deleteTag(id: Int!): Tag!
}
type Principle {
id: Int!
title: String!
description: String!
tags: [Tag]
createdAt: DateTime!
modifiedAt: DateTime!
}
type Query {
redwood: Redwood
principles(searchQuery: String, tagIds: [Int]): [Principle!]!
tags: [Tag!]!
tagsByLabel(searchTerm: String): [TagCount!]!
tag(id: Int!): Tag!
}
type Redwood {
version: String
}
type Tag {
id: Int!
title: String!
principles: [Principle]
description: String
createdAt: DateTime!
modifiedAt: DateTime!
}
type TagCount {
id: Int!
title: String!
count: Int!
principles: [Principle]
description: String
createdAt: DateTime!
modifiedAt: DateTime!
}
# A time string at UTC, such as 10:15:30Z, compliant with the `full-time` format
# outlined in section 5.6 of the RFC 3339profile of the ISO 8601 standard for
# representation of dates and times using the Gregorian calendar.
scalar Time
input UpdatePrincipleInput {
title: String
description: String
}
input UpdateTagInput {
title: String
description: String
}
3 ответа
Не похоже, что вы используете Prisma 2. Prisma 2 использует модели (не типы) и имеет массивы, классифицированные как Principles[] vs [Principles]. Возможно, Redwood выполняет преобразование (никогда не использовал его).
Я создал вашу модель в Prisma 2 и использовал следующую команду, чтобы получить единый принцип, с которым связаны два тега. Имейте в виду, что идентификаторы взяты из моего тестового набора данных. Надеюсь, вы сможете изменить это в своем коде. Если нет, создайте песочницу / площадку с минимальным кодом для тестирования.
export const principles = async ({ searchQuery, tagIds }) => {
const payload = {
where: {
OR: [
{ title: { contains: searchQuery } },
{ description: { contains: searchQuery } },
],
userId: userIdFromSession,
},
}
if (tagIds.length) {
const whereAnd = []
tagIds.forEach((tagId) => {
whereAnd.push({
tags: { some: { id: tagId } },
})
})
payload.where.AND = whereAnd
}
const result = await db.principle.findMany(payload)
return result
}
Вы можете попробовать что-то вроде этого
export const principles = ({ searchQuery, tagIds }) => {
const payload = {
where: {
OR: [
{ title: { contains: searchQuery } },
{ description: { contains: searchQuery } },
],
// using the `in` operator like this
tagId: { in: tagIds },
userId: userIdFromSession,
},
}
console.log('db.principle.findMany(payload)', payload)
return db.principle.findMany(payload)
}
Это должно делать свое дело!
Мне пришлось прибегнуть к использованиюAND
для чего-то подобного - надеюсь, это поможет!
const tagIds = [9,6];
where: {
// ...
AND: tagIds.map(tagId => ({
tags: {
some: {
id: {
equals: tagId,
},
},
},
})),
}