Skip to content

feat: add logical not query operator#16067

Open
ollieabbey wants to merge 1 commit intopayloadcms:mainfrom
ollieabbey:add_logical_not_query_operator
Open

feat: add logical not query operator#16067
ollieabbey wants to merge 1 commit intopayloadcms:mainfrom
ollieabbey:add_logical_not_query_operator

Conversation

@ollieabbey
Copy link
Copy Markdown

What?

Add a not operator to where queries that allows you to negate the child query, alongside and and or.

Why?

Allows you to check the inverse of something. While this is already possible with some operators (e.g. equals has not_equals), I don't think it's possible to invert more complex conditions.

E.g. say there is an array field 'categories', we can currently query that the array contains a value

where: {
  categories: {
    contains: 'news'
  }
}

But now you can invert that to find documents that don't have the category news

where: {
  categories: {
	not: {
	  contains: 'news'
	}
  }
}

How?

Using the existing drizzle & mongoose apis for negating a query (mongoose uses nor rather than not, as not only accepts a field level expression, while nor accepts a full filter expression).

Copy link
Copy Markdown
Member

@r1tsuu r1tsuu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's initial feedback:

// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
and?: Where[]
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
not?: Where
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should change this to _not in case if someone has field not defined so it won't be breaking for them. We explicitly say that fields that start with _ are internal

@@ -0,0 +1,256 @@
import type { Payload } from 'payload'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like this test to exist in the database folder. However, you can create there a subfolder so you have a separate config from database like for example here https://github.com/payloadcms/payload/blob/main/test/database/migrate-to-blocks-as-json/config.ts

Comment on lines +240 to +250
it('should support not operator with nested relationship properties', async () => {
const { docs } = await payload.find({
collection: postsSlug,
where: {
not: {
'category.name': {
equals: 'cat1',
},
},
},
})
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need some coverage with versions too.
payload.findVersions
payload.find({ draft: true }) - internally uses db.queryDrafts and I think this might actually fail

and with access control, ensure
not: { field: { equals } } cannot be queried if the user does not have access to field

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants