Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support sparse unique indexes #3419

Open
Tracked by #16311
janpio opened this issue Dec 18, 2019 · 30 comments
Open
Tracked by #16311

Support sparse unique indexes #3419

janpio opened this issue Dec 18, 2019 · 30 comments

Comments

@janpio
Copy link
Member

janpio commented Dec 18, 2019

During the backend meeting it came up that we might want to test "sparse unique indexes". Backend team (probably @sorenbs) has more context.

@pantharshit00
Copy link
Contributor

I need more context indeed for this. I want to know whether this refers to multi column indexes or many uniques index on fields of the same model.

@janpio
Copy link
Member Author

janpio commented Dec 19, 2019

My understanding:
"sparse unique indexes" are its own concept: https://docs.mongodb.com/manual/core/index-sparse/ So it is a unique index on a field, where many instances of NULL are allowed for example.

@sorenbs might be able to provide more context, he mentioned it.

@cotterjd
Copy link

Is sparse unique indexes still on the agenda? I would really like to see that feature in Prisma.

@janpio janpio transferred this issue from prisma/prisma-client-js Aug 24, 2020
@janpio janpio added kind/feature A request for a new feature. topic: schema labels Aug 24, 2020
@janpio janpio added the team/schema Issue for team Schema. label Mar 23, 2021
@janpio janpio changed the title sparse unique indexes Support sparse unique indexes May 29, 2021
@HommeSauvage
Copy link

This is a very useful feature where a user can have either an email address or phone number as login and one of the 2 can be null. We still need a @unique index on these 2 fields. Currently, I add the sparse indexes manually, but it would be amazing if prisma supported them.

@mattslight
Copy link

mattslight commented Sep 15, 2022

I've also come up against this error. Sparse unique indexes in MongoDB enforce only non-null values to be unique which is a very handy feature. If i can help with this feature dev please let me know how

Screen.Recording.2022-09-15.at.11.10.09.PM.mov

Edit: If I try and push the schema without the unique clause I get an error telling me one-to-one relations must use unique fields. So it's a bit of a catch 22 situation.

Error: P1012

error: Error parsing attribute "@relation": A one-to-one relation must use unique fields on the defining side. Either add an `@unique` attribute to the field `driverId`, or change the relation to one-to-many.
  -->  schema.prisma:81
   | 
80 |   name     String  @unique
81 |   driver   User?   @relation(fields: [driverId], references: [id])
82 |   driverId String? @db.ObjectId

@mattslight
Copy link

mattslight commented Sep 28, 2022

suggest to add the feature using the keyword @sparse in the schema eg:

model Candidate {
  id               String    @id @default(auto()) @map("_id") @db.ObjectId
  firstName        String?
  lastName         String?
  email            String?   @unique @sparse
}

I could take a look at a PR if agreed? @janpio @sorenbs

@janpio
Copy link
Member Author

janpio commented Sep 28, 2022

We will want to design this feature in a bigger context, and unfortuantely we are currently not set up great to accept contributions with our distributed codebase in Prisma Client and Prisma Engines.

We are looking into adding some index options soon, so maybe this could be one of them.

Can a field that has a sparse index also have other indexes (unique or normal)?
Seems yes since Mongo 5: https://www.mongodb.com/docs/manual/core/index-sparse/#sparse-and-non-sparse-unique-indexes

What about this note from Mongo docs:

Changed in version 3.2: Starting in MongoDB 3.2, MongoDB provides the option to create partial indexes. Partial indexes offer a superset of the functionality of sparse indexes. If you are using MongoDB 3.2 or later, partial indexes should be preferred over sparse indexes.

? We have a request for partial indexes already: #3076

@mattslight
Copy link

mattslight commented Sep 28, 2022 via email

@janpio
Copy link
Member Author

janpio commented Sep 28, 2022

Right now the biggest help would be in understanding exactly how sparse works.

From reading the docs you linked to it seems that it exists for both unique and non unique indexes, which points to an additional configuration type for @unique, @@unique and @@index. But at the same time you can have both a sparse and a non sparse variant at the same time - which would clash with how we currently define at least @unique. There your @sparse suggestions might be better - but of course that you would need to differentiate between unique and index in there also seems wrong.

Am I missing something else?

@mattslight
Copy link

mattslight commented Sep 29, 2022 via email

@janpio
Copy link
Member Author

janpio commented Sep 29, 2022

As sparse indexes can be either normal indexes or unique indexes, and both can exist on the same field, I do not think it is as simple. I am also not clear if this really justifies a full new attribute, instead of becoming a modifier - although it then also requires changing the rules for those so some use cases are possible.

@mattslight
Copy link

mattslight commented Sep 29, 2022 via email

@janpio
Copy link
Member Author

janpio commented Sep 29, 2022

I meant something like @unique(sparse: true) or similar. That would make clearer how this is just a "variant" of a normal index/constraint. And the problem with this suggestion is, that one field only accepts one @unique value right now afaik.

@mattslight
Copy link

mattslight commented Sep 29, 2022 via email

@arthurfiorette
Copy link
Contributor

Yup, a paremeter seems better than another @keyword. There's anything that we can do for now to create sparse indexes?

@janpio
Copy link
Member Author

janpio commented Sep 29, 2022

You can probably just create it manually on your collection and it should work. (Of course I have no idea what running db push would do though.)

What is a bit unknown and will need some research on our side, is how this influences non MongoDB databases. This issue is from a time when Prisma had no MongoDB support, and there was some idea that we would need to do something about it. (From the issue description it is clear that I was not the one knowing what they talk about here though.)

@mattslight
Copy link

mattslight commented Sep 30, 2022 via email

@janpio
Copy link
Member Author

janpio commented Sep 30, 2022

@@index([...], sparse: true) would also need to exist I guess.

@mattslight
Copy link

mattslight commented Oct 1, 2022 via email

@janpio
Copy link
Member Author

janpio commented Mar 25, 2023

I learned that sparse indexes are sometimes (when you request more documents than contained in the index) only used by queries with a hint(). That poses a challenged for implementing this in Prisma Client. The Prisma Schema definition, Migration and Introspection should be fine and straightforward - but the Client has no concept of index hints at all yet and I am not sure how an API for that could/should look like. How common is that case? Do we even need that API or can we suggest to fall back to raw queries for that?

@gustawdaniel
Copy link

@janpio I have real case from app.

User can have property, eg.: telegram_id but it it optional. On the other hand I would to see error if second user will use the same telegram_id.

Now I have two options:
a) set index and then more than one user can't have telegram_id = null // this is unacceptable
b) remove index and then manually check if it is unique instead of use index // this is not optimal

For me it would be enough if I would be able to describe this use case in schema and unblock:

#17689

Even docs about recommended method of appending custom mongo indexes to prisma schema would be useful.


Btw I know rust, typescript and prisma, so I can try to help with this issue if you will give me some introduction.

@lucy2329
Copy link

Hey guys, is there any update on this?

@lucasrossell
Copy link

Also experiencing this issue, which is forcing us to create one-to-many relationships that realistically should be able to be one-to-one. something like @unique(sparse: true) would be much appreciated

@boredland
Copy link

I wanted to follow the instructions to create a optional 1:1 relation, but am on MongoDB. I'd say this just doesn't work on MongoDB due to the lack of the sparse index feature. Am I wrong?

@boredland
Copy link

boredland commented Nov 10, 2023

Another problem I face: declaring a unique index across optional fields makes them non-optional, for example in the where clause of an upsert, so I can't even work around this.

@chloehjung15
Copy link

Any update on this? I want to create a optional 1:1 relation using MongoDB and I can't do that at the moment

@andrey-hohlov
Copy link

I just started doing my first steps with Prisma and stuck with issue that is already 5 year here. Very sad

@Nik-Novak
Copy link

I just started doing my first steps with Prisma and stuck with issue that is already 5 year here. Very sad

It seems @janpio is going to finally resolve this.

@gustavoggsb
Copy link

Do we have any updates on this?

@saoudi-h
Copy link

It literally took Mikro-ORM one line of code and one day from the issue to the PR to address this problem VS ...

mikro-orm/mikro-orm#484

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests