Как я могу использовать «считать» и «группировать по» в Prisma 2? - PullRequest
1 голос
/ 04 мая 2020

У меня есть эта функция, которая работает:

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
  }
]

Я вижу пример docs из prisma.user.count(), но, похоже, он возвращает простой подсчет результата всего запроса, а не подсчет как поле "group by".

Я использую Redwood Js, Prisma 2, Apollo, GraphQL.

Ответы [ 2 ]

1 голос
/ 04 мая 2020

На данный момент groupBy поддержка по-прежнему действует c здесь , поэтому в настоящее время вы можете использовать count только с указанием c запросов.

Как Обходной путь, вы должны использовать prisma.raw для времени.

0 голосов
/ 05 мая 2020

В моем 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
}

Но, как уже упоминалось в комментарии, я все еще пытаюсь выяснить, как получить безопасная параметризация рабочая.

...