如何在 Prisma 2 中使用“计数”和“分组依据”?
Posted
技术标签:
【中文标题】如何在 Prisma 2 中使用“计数”和“分组依据”?【英文标题】:How can I use "count" and "group by" in Prisma 2? 【发布时间】:2020-08-18 08:33:40 【问题描述】:我有这个有效的功能:
export const tagsByLabel = async (params) =>
const findManyParams =
where: userId: userIdFromSession ,
orderBy: title: "asc" ,
;
if (params)
const searchTerm = params;
findManyParams.where.title = contains: searchTerm ;
console.log("findManyParams", findManyParams);
const tagsByLabelResult = await db.tag.findMany(findManyParams);
console.log("tagsByLabelResult", tagsByLabelResult);
return tagsByLabelResult;
;
如果我搜索“mex”,我会看到:
findManyParams
where: userId: 1, title: contains: 'mex' ,
orderBy: title: 'asc'
tagsByLabelResult [
id: 9,
title: 'mex',
description: 'Mexican food',
userId: 1,
createdAt: 2020-05-03T22:16:09.134Z,
modifiedAt: 2020-05-03T22:16:09.134Z
]
对于空查询,tagsByLabelResult
包含所有标签记录。
如何调整我的tagsByLabel
函数以聚合(使用“分组依据”)记录并按计数降序为tagsByLabelResult
的每条记录输出一个“计数”?
tagsByLabelResult [
id: 9,
title: 'mex',
description: 'Mexican food',
count: 25,
userId: 1,
createdAt: 2020-05-03T22:16:09.134Z,
modifiedAt: 2020-05-03T22:16:09.134Z
]
我看到prisma.user.count()
的docs example,但这似乎检索了整个查询结果的简单计数,而不是作为具有“分组依据”的字段的计数。
我正在使用 RedwoodJs、Prisma 2、Apollo、GraphQL。
【问题讨论】:
【参考方案1】:到目前为止,groupBy
支持仍在规范中,here 因此目前您只能在特定查询中使用count
。
作为一种解决方法,您暂时必须使用prisma.raw
。
【讨论】:
好的,我去看看prisma.io/docs/reference/tools-and-interfaces/prisma-client/…。谢谢。【参考方案2】:在我的tags.sdl.js
我需要添加:
type TagCount
id: Int!
title: String!
count: Int!
principles: [Principle]
description: String
createdAt: DateTime!
modifiedAt: DateTime!
并将查询 tagsByLabel(searchTerm: String): [Tag!]!
更改为 tagsByLabel(searchTerm: String): [TagCount!]!
在我的TagsAutocomplete.js
组件中,我现在有:
export const TagsAutocomplete = ( onChange, selectedOptions, closeMenuOnSelect ) =>
const state =
isLoading: false,
;
const client = useApolloClient();
const promiseOptions = useCallback(
async (searchTerm) =>
try
const data = await client.query(
query: QUERY_TAGS_BY_LABEL,
variables: searchTerm ,
);
console.log("promiseOptions data", data);
const tags = data.tags.map((tag) =>
if (!tag.label.includes("("))
//ONEDAY why does the count keep getting appended if this condition isn't checked here?
tag.label = tag.label + " (" + tag.count + ")";
return tag;
);
console.log("promiseOptions tags", tags);
return tags;
catch (e)
console.error("Error fetching tags", e);
,
[client]
);
;
在我的tags.js
服务中,我现在拥有:
export const tagsByLabel = async (params) =>
let query = `
SELECT t.*, COUNT(pt.B) as count FROM tag t LEFT JOIN _PrincipleToTag pt ON t.id = pt.B WHERE t.userId = $userIdFromSession `;
if (params)
const searchTerm = params;
if (searchTerm)
query += `AND t.title LIKE '%$searchTerm%' `;
query += "GROUP BY t.id ORDER BY count DESC, t.title ASC;";
console.log("query", query);
const tagsByLabelResult = await db.raw(query);
//TODO get secure parameterization working
console.log("tagsByLabelResult", tagsByLabelResult);
return tagsByLabelResult;
;
但是,正如评论中提到的,我仍在试图弄清楚如何让secure parameterization 工作。
【讨论】:
嗨@Ryan,您可能已经知道如何安全地参数化,但如果您还没有,我会这样做。基于:prisma.io/docs/reference/tools-and-interfaces/prisma-client/… 我设法让它在这里工作:gist.github.com/Aidurber/a8c9b97b994fa4a0e46a9243ba378a79 这真的很丑,我找不到一个干净的抽象来使它更通用一点,但它可以解决问题。 @ZeroBased_IX 感谢您的留言;我会检查一下。以上是关于如何在 Prisma 2 中使用“计数”和“分组依据”?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 prisma 2 或 3 和 nexus 模式生成同时生成生成的 crud 和“ondelete 级联”
如何在 prisma 中使用 connectOrCreate 与多对多