如何在 Prisma 2 中使用 "count" 和 "group by"?
How can I use "count" and "group by" in Prisma 2?
我有这个功能有效:
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。
截至目前 groupBy
支持仍在规范中 here 因此目前您只能使用 count
进行特定查询。
作为解决方法,您暂时必须使用 prisma.raw
。
在我的 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 工作。
我有这个功能有效:
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。
截至目前 groupBy
支持仍在规范中 here 因此目前您只能使用 count
进行特定查询。
作为解决方法,您暂时必须使用 prisma.raw
。
在我的 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 工作。