Hi guys, i want to create 2 collection like this. ...
# mongodb
ö
Hi guys, i want to create 2 collection like this.
Copy code
const tags = [
  {
    id: '1111111',
    name: 'big',
  },
  {
    id: '2222222',
    name: 'white',
  },
  {
    id: '3333333',
    name: 'expensive',
  },
];

const products = [
  {
    id: 'aaaaaaaa',
    name: 'dress',
    price: 100,
    tags: ['1111111', '2222222'],
  },
  {
    id: 'bbbbbbbb',
    name: 'dress 2',
    price: 101,
    tags: ['1111111', '3333333'],
  },
];
I used many-to-many relation and result this.
Copy code
const tags = [
  {
    id: '1111111',
    name: 'big',
    products: ['aaaaaa', 'bbbbbbb'],
  },
  {
    id: '2222222',
    name: 'white',
    products: ['aaaaaa'],
  },
  {
    id: '3333333',
    name: 'expensive',
    products: ['bbbbbbb'],
  },
];

const products = [
  {
    id: 'aaaaaaaa',
    name: 'dress',
    price: 100,
    tags: ['1111111', '2222222'],
  },
  {
    id: 'bbbbbbbb',
    name: 'dress 2',
    price: 101,
    tags: ['1111111', '3333333'],
  },
];
this is my schema
Copy code
model Product {
  id   String @id @default(auto()) @map("_id") @db.ObjectId
  name String

  tagIDs String[] @db.ObjectId
  tags   Tag2[]   @relation(fields: [tagIDs], references: [id])
}

model Tag2 {
  id String @id @default(auto()) @map("_id") @db.ObjectId

  productIDs String[]  @db.ObjectId
  products   Product[] @relation(fields: [productIDs], references: [id])
}
Thank you...
1
m
You only need the ids of the relation on one side of the relation.
Copy code
model Product {
  id   String @id @default(auto()) @map("_id") @db.ObjectId
  name String

  tagIds String[] @db.ObjectId
  tags   Tag[]   @relation(fields: [tagIds], references: [id])
}

model Tag {
  id String @id @default(auto()) @map("_id") @db.ObjectId
  products Product[]
}
ö
@Marcus Are you sure ? I get an error when I try to npx prism push
m
You are right. You I missed the n to m Maybe naming your relation solves your problem
Copy code
tagIds            String[]                 @db.ObjectId
  tags              Tag[]              @relation("TagsProducts", fields: [tagIds], references: [id])
...
  productIds            String[]                @db.ObjectId
  products               Product[]                 @relation("TagsProducts", fields: [productIds], references: [id])
n
This schema is correct:
Copy code
model Product {
  id     String   @id @default(auto()) @map("_id") @db.ObjectId
  name   String
  tagIds String[] @db.ObjectId
  tags   Tag[]    @relation(fields: [tagIds], references: [id])
}

model Tag {
  id         String    @id @default(auto()) @map("_id") @db.ObjectId
  name       String
  productIDs String[]  @db.ObjectId
  products   Product[] @relation(fields: [productIDs], references: [id])
}
Here’s a query that I tried:
Copy code
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient({
  log: ['query'],
});

async function main() {
  await prisma.tag.deleteMany();

  const tagId = `6310a962263858da3df4ecf0`;

  const tag = await prisma.tag.create({
    data: {
      id: tagId,
      name: 'tag1',
    },
  });

  console.log('tag', tag);

  const product = await prisma.product.create({
    data: {
      name: 'product1',
      tags: {
        connect: {
          id: tagId,
        },
      },
    },
  });

  console.log('product', product);
}

main()
  .catch((e) => {
    throw e;
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
And here’s the response
Copy code
> ts-node index.ts

prisma:query db.Tag.aggregate([ { $match: { $expr: { }, }, }, { $project: { _id: 1, }, }, ])
prisma:query db.Tag.aggregate([ { $match: { $expr: { }, }, }, { $project: { _id: 1, }, }, ])
prisma:query db.Tag.deleteMany({ _id: { $in: [ ObjectId("6310a962263858da3df4ecf0"), ], }, })
prisma:query db.Tag.insertOne({ _id: ObjectId("6310a962263858da3df4ecf0"), name: "tag1", })
prisma:query db.Tag.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $eq: [ "$_id", ObjectId("6310a962263858da3df4ecf0"), ], }, { $or: [ { $ne: [ { $ifNull: [ "$_id", null, ], }, null, ], }, { $eq: [ "$_id", null, ], }, ], }, ], }, ], }, }, }, { $project: { _id: 1, name: 1, productIDs: 1, }, }, ])

tag { id: '6310a962263858da3df4ecf0', name: 'tag1', productIDs: [] }

prisma:query db.Product.insertOne({ name: "product1", })
prisma:query db.Tag.aggregate([ { $match: { $expr: { $or: [ { $and: [ { $and: [ { $eq: [ "$_id", ObjectId("6310a962263858da3df4ecf0"), ], }, { $or: [ { $ne: [ { $ifNull: [ "$_id", null, ], }, null, ], }, { $eq: [ "$_id", null, ], }, ], }, ], }, ], }, ], }, }, }, { $project: { _id: 1, }, }, ])
prisma:query db.Product.updateOne({ _id: { $eq: ObjectId("6310a9e6152da0a94f164aef"), }, }, { $addToSet: { tagIds: { $each: [ ObjectId("6310a962263858da3df4ecf0"), ], }, }, })
prisma:query db.Product.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $eq: [ "$_id", ObjectId("6310a9e6152da0a94f164aef"), ], }, { $or: [ { $ne: [ { $ifNull: [ "$_id", null, ], }, null, ], }, { $eq: [ "$_id", null, ], }, ], }, ], }, ], }, }, }, { $project: { _id: 1, name: 1, tagIds: 1, }, }, ])

product {
  id: '6310a9e6152da0a94f164aef',
  name: 'product1',
  tagIds: [ '6310a962263858da3df4ecf0' ]
}
The product response is as you are expecting but for the tags model, there would be an empty productIDs array.
ö
@Nurul If you write tags to console after adding products. I think you will see tag.productIDs = ["6310a9e6152da0a94f164aef"]
Maybe I can use this schema. Thank you guys for giving a time
n
That’s true, it would connect the productID to Tags after the connect query.