postgresql prisma按关系排序只有_count属性,不能按关系字段排序

jexiocij  于 2023-04-11  发布在  PostgreSQL
关注(0)|答案(3)|浏览(256)

考虑以下Prisma模式:

model Conversation {
  id           Int                         @id @default(autoincrement())
  createdAt    DateTime                    @db.Timestamp(6)
  messages     ConversationMessage[]
}

model ConversationMessage {
  id             Int                     @id @default(autoincrement())
  text           String                  @db.VarChar(1000)
  sentAt         DateTime                @map("sent_at") @db.Timestamp(6)
  conversationId Int?                    @map("conversation_id")
  userId         Int?                    @map("user_id")
  conversation   Conversation?           @relation(fields: [conversationId], references: [id])
  sender         User?                   @relation(fields: [userId], references: [id])
}

我想运行这样的查询,以便获得按消息日期排序的对话列表,即首先有新消息的对话。

prisma.conversation.findMany({
    orderBy: {
        messages: {
            sentAt: 'desc'
        }
    },
    ...
})

但是我现在唯一可以查询的方法是这样的,即关系只有_count属性。

prisma.conversation.findMany({
    orderBy: {
        messages: {
           '_count': 'desc'
        }
     },
     ...
})

环境和设置

OS: Mac OS,
    Database: PostgreSQL
    Node.js version: v12.19.0

Prisma版本

prisma               : 2.24.1
@prisma/client       : 2.24.1
Current platform     : darwin
Query Engine         : query-engine 18095475d5ee64536e2f93995e48ad800737a9e4 (at node_modules/@prisma/engines/query-engine-darwin)
Migration Engine     : migration-engine-cli 18095475d5ee64536e2f93995e48ad800737a9e4 (at node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine : introspection-core 18095475d5ee64536e2f93995e48ad800737a9e4 (at node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary        : prisma-fmt 18095475d5ee64536e2f93995e48ad800737a9e4 (at node_modules/@prisma/engines/prisma-fmt-darwin)
Default Engines Hash : 18095475d5ee64536e2f93995e48ad800737a9e4
Studio               : 0.397.0
Preview Features     : orderByRelation

谢谢你!

5ktev3wc

5ktev3wc1#

虽然Prisma V2.19引入了按关系聚合值排序,但在撰写本文时,唯一支持的聚合属性是count。据我所知,Prisma目前不直接支持您所要求的内容。如果他们添加minmax聚合属性进行排序,则可能会有。
一个可能的解决方案是在检索后对Node.js中的消息进行排序。我添加了一个使用orderByRelation预览功能的解决方案,以简化排序并确保会话中的消息始终按顺序排列(最新的优先)。

更新Prisma客户端使用orderByRelation预览功能。

首先,更新schema.prisma以添加预览特性

generator client {
  provider = "prisma-client-js"
  previewFeatures = ["orderByRelation"]
}

现在更新prisma客户端

prisma generate client

获取conversations并按最近消息排序

// Assuming inside an async function 

let unsortedConversations = await prisma.conversation.findMany({
    include: {
        messages: {
            orderBy: {    
                sentAt: 'desc'  // messages for each converastion will be ordered newest first. 
            }
        }
    },
    // other conditions
})

unsortedConversations包含所有必需的会话,但它们是无序的。您可以通过创建自定义比较器函数来按所需的顺序对其进行排序。

function conversationComparatorFunction(conversationA, conversationB) {
    // Conversations with 0 messages will be placed last in arbitrary order. 
    if (!conversationB.messages.length) return 1;  
    if (!conversationA.messages.length) return -1;
    
    // sort conversations based on sentAt date of the first message. 
    // since messages were previously sorted, messages[0] always contain the most recent message. 
    if (conversationA.messages[0].sentAt > conversationB.messages[0].sentAt) {
        return -1;
    } else if (conversationA.messages[0].sentAt < conversationB.messages[0].sentAt) {
        return 1;
    } else return 0;

}

let sortedConversations = unsortedConversations.sort(conversationComparatorFunction)

但是要注意,如果Conversation记录的数量非常大,那么应用程序端的排序可能会导致性能低下,特别是考虑到Node.js是单线程的。

h43kikqp

h43kikqp2#

一个不使用其他包的简单答案是创建一个属性:
lastChildUpdatedAt PS:随你怎么命名
当创建一个新的子对象或更新一个子对象时,也会更新父对象上的此属性。然后,当获取时,用途:

orderBy: {
  lastChildUpdatedAt: "desc",
}
yduiuuwa

yduiuuwa3#

OrderBy关系仍然是预览功能-您需要确保使用功能标志

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["orderByRelation"]
}

https://www.prisma.io/docs/concepts/components/prisma-client/filtering-and-sorting#sort-by-relation-preview

相关问题