【问题标题】:Typeorm: Query to check if all the values exist in the many-to-many relation?Typeorm:查询以检查多对多关系中是否存在所有值?
【发布时间】:2021-08-29 18:41:39
【问题描述】:

我有一个与成员有多对多关系的对话实体。我正在尝试返回与确切指定用户的对话。我下面的代码有效,但它太多了,我想简化它。

conversation.entity.ts

@Entity()
export class Conversation {

    readonly __typename: string = 'Conversation';

    @ManyToMany(() => User)
    @JoinTable()
    members: User[];

    @ManyToMany(() => Order)
    @JoinTable()
    orders: Order[];

    @ManyToMany(() => Product)
    @JoinTable()
    products: Product[];

    @ManyToMany(() => Request)
    @JoinTable()
    requests: Request[];
}

我有一个函数可以获取成员一的所有对话 ID,然后获取成员二的所有对话 ID。然后我只是过滤两个返回的 ID 数组以获得最多应该是一个的公共 ID 数组。

获取对话的功能:

async findOneByAllMembers(ctx: RequestContext, input: FindConversationInput) {
        const { memberUserIds } = input;
        if (memberUserIds.length !== 2) {
            throw new UserInputError('Member IDs are not equal to 2');
        }

        const conversationFromMemberOne = await this.connection
            .getRepository(ctx, Conversation)
            .createQueryBuilder('conversation')
            .select('conversation.id')
            .innerJoin('conversation.members', 'members')
            .where('members.id = :memberId', { memberId: memberUserIds[0] })
            .getMany()
            .then(items => {
                const ids = items.map(val => val.id);
                return ids;
            });

        const conversationFromMemberTwo = await this.connection
            .getRepository(ctx, Conversation)
            .createQueryBuilder('conversation')
            .select('conversation.id')
            .innerJoin('conversation.members', 'members')
            .where('members.id = :memberId', { memberId: memberUserIds[1] })
            .getMany()
            .then(items => {
                const ids = items.map(val => val.id);
                return ids;
            });

        const filteredArray = conversationFromMemberOne.filter(value =>
            conversationFromMemberTwo.includes(value),
        );

        console.log(filteredArray);

        return filteredArray;
    }

此代码有效,但我想将我的 sql 查询限制为一个。有没有办法和里面的两个成员对话?

【问题讨论】:

    标签: node.js typescript orm typeorm


    【解决方案1】:

    我已经在本地尝试过,这应该可以:

    const conversations: Conversation[] = await this.connection
        .createQueryBuilder()
        .select('conversation.id')
        .from(Conversation, 'conversation')
        .innerJoin('conversation.members', 'member')
        .where('member.id = :id', { id: memberUserIds[0] })
        .andWhere(
          (qb) =>
            `conversation.id IN ${qb
              .subQuery()
              .select('conversation.id')
              .from(Conversation, 'conversation')
              .innerJoin('conversation.members', 'member')
              .where('member.id = :id', { id: memberUserIds[1] })
              .getQuery()}`,
        )
        .getMany();
    
    const conversationsIds: number[] = conversations.map((conversation) => conversation.id);
    

    首先,选择第一个用户的所有会话ID。

    其次,通过检查 id 是否为 IN 第二个用户的“过滤”它们。

    最后但同样重要的是,映射结果 (conversations) 以仅获取对话 ID 数组 (conversationsIds),这是一个“纯”数字数组。

    我正在使用 子查询;请参阅this 了解更多信息。

    PS:请记住,查询可能会失败,因此请用trycatch 将其括起来。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-02
      • 1970-01-01
      • 1970-01-01
      • 2014-05-28
      • 1970-01-01
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多