question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Handle where clauses correctly for records where the field is `null` or `not defined` - MongoDB

See original GitHub issue

Problem

All ID’s removed for abrreviation


model Test {
  /// mandatory
  id String @id @default(auto()) @map("_id") @db.ObjectId
  /// just to differentiate
  name String @unique 

  nullable Boolean? // <--- This
}

When you declare a model with a nullable field, let’s say Test (as described above), we can end up with 3 possible documents in our MongoDB databases.

// 1: `nullable` is optional but has a null value
PRISMA.test.create({ data: { name: 'with null', nullable: null } });
databaseRecord = { name: 'with null', nullable: null }
// 2: `nullable` is optional but specified
PRISMA.test.create({ data: { name: 'with true', nullable: true } });
databaseRecord = { name: 'with true', nullable: true }
// 3: `nullable` is optional and ignored
PRISMA.test.create({ data: { name: 'empty' } });
databaseRecord = { name: 'empty' }

And that should be the desired behaviour, as we can save bytes with these null optional fields.

But the problem occurs when we try to filter these documents. Simply by using where: { nullable: { not: null } } or where: { nullable: null }, the 3rd option gets filtered out.

console.log({
  nulls: await PRISMA.test.findMany({ where: { nullable: null }, }),
  notNulls: await PRISMA.test.findMany({ where: { nullable: { not: null } }, }),
  all: await PRISMA.test.findMany(),
});

result = {
  nulls: [{ name: 'with null', nullable: null }],
  notNulls: [{ name: 'with true', nullable: true }],
  all: [
    { name: 'with null', nullable: null },
    { name: 'with true', nullable: true },
    // The nullable field is present here, instead of just a { name: 'empty' } object,
    // which would cause obj.nullable to return undefined.
    { name: 'empty', nullable: null }, 
  ],
};

Suggested solution

As said before, I don’t think that use null values instead of not setting fields is a good way. Because we can save up a lot of bytes if we take in comparison a multi million record collection.

This issue maybe should have been created in the rust side of this project, but I’m not familiar enought with prisma arquitecture.

Anyways, I think that transforming the query to handle both options (not present & present and null) like this stackoverflow post does for the native mongodb javascript driver is good enough.

Alternatives

I don’t mind any other alternative, as long it works as intended 😃

Additional context

  • MongoDB 5.0
  • Prisma Client ^3.15.2
  • Prisma ^3.15.2

MongoDB Compass Test collection screenshot:

image

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
arthurfiorettecommented, Jun 22, 2022

@janpio https://github.com/arthurfiorette/prisma-issue-13949

Outputs:

Created entities:
{
  withNull: { id: '62b3762171bf26e40b14616a', name: 'with null', nullable: null },
  withTrue: { id: '62b3762171bf26e40b14616b', name: 'with true', nullable: true },
  empty: { id: '62b3762171bf26e40b14616c', name: 'empty', nullable: null }
}

Filtered records
{
  nulls: [
    {
      id: '62b3762171bf26e40b14616a',
      name: 'with null',
      nullable: null
    }
  ],
  notNulls: [
    {
      id: '62b3762171bf26e40b14616b',
      name: 'with true',
      nullable: true
    }
  ],
  all: [
    {
      id: '62b3762171bf26e40b14616a',
      name: 'with null',
      nullable: null
    },
    {
      id: '62b3762171bf26e40b14616b',
      name: 'with true',
      nullable: true
    },
    { id: '62b3762171bf26e40b14616c', name: 'empty', nullable: null }
  ]
}
1reaction
dpetrickcommented, Jun 23, 2022

This is intended behavior.

You can filter these fields with isSet: true/false: https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#isset

The null/undefined result discussion can be tracked here: https://github.com/prisma/prisma/issues/12555

Read more comments on GitHub >

github_iconTop Results From Across the Web

Query for Null or Missing Fields — MongoDB Manual
The query returns only the document where the item field has a value of null . Existence Check. The following example queries for...
Read more >
MongoDB: How to query for records where field is null or not ...
The { item : null } query matches documents that either contain the item field whose value is null or that do not...
Read more >
Null and undefined (Reference) - Prisma
Prisma Client differentiates between null and undefined : null is a value. undefined means do nothing.
Read more >
Handle null values in query expressions (LINQ in C#)
In the previous example, the where clause filters out all null elements in the categories sequence. This technique is independent of the null...
Read more >
4. Querying - MongoDB: The Definitive Guide, 2nd Edition [Book]
You can query for ranges, set inclusion, inequalities, and more by using $ -conditionals. Queries return a database cursor, which lazily returns batches...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found