【问题标题】:How can I use "count" and "group by" in Prisma 2?如何在 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。

【问题讨论】:

    标签: react-apollo prisma prisma-graphql redwoodjs


    【解决方案1】:

    到目前为止,groupBy 支持仍在规范中,here 因此目前您只能在特定查询中使用count

    作为一种解决方法,您暂时必须使用prisma.raw

    【讨论】:

    【解决方案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 工作。

    【讨论】:

    猜你喜欢
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 2016-10-17
    • 2020-08-14
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多