feat(index): $nin and $not operators (#13289)

* feat(index): add $not and $nin operators

* logical operator

* test

* test

* types

* logical

* schema ID

* types and $ilike fix

* index type
This commit is contained in:
Carlos R. L. Rodrigues
2025-08-28 11:56:17 +02:00
committed by GitHub
parent b3fb0f7634
commit f764b3a364
8 changed files with 268 additions and 24 deletions
@@ -1,6 +1,6 @@
export const schema = `
type Product @Listeners(values: ["product.created", "product.updated", "product.deleted"]) {
id: String
id: ID
title: String
created_at: DateTime
@@ -18,7 +18,7 @@ export const schema = `
}
type ProductVariant @Listeners(values: ["variant.created", "variant.updated", "variant.deleted"]) {
id: String
id: ID
product_id: String
sku: String
prices: [Price]
@@ -1,13 +1,13 @@
export const updateRemovedSchema = `
type Product @Listeners(values: ["product.created", "product.updated", "product.deleted"]) {
id: String
id: ID
title: String
handle: String
variants: [ProductVariant]
}
type ProductVariant @Listeners(values: ["variant.created", "variant.updated", "variant.deleted"]) {
id: String
id: ID
product_id: String
sku: String
description: String
@@ -1,6 +1,6 @@
export const updatedSchema = `
type Product @Listeners(values: ["product.created", "product.updated", "product.deleted"]) {
id: String
id: ID
title: String
handle: String
deep: InternalNested
@@ -17,7 +17,7 @@ export const updatedSchema = `
}
type ProductVariant @Listeners(values: ["variant.created", "variant.updated", "variant.deleted"]) {
id: String
id: ID
product_id: String
sku: String
prices: [Price]
@@ -135,6 +135,7 @@ describe("IndexModuleService query", function () {
name: "Product",
data: {
id: "prod_1",
title: "Product 1",
},
},
{
@@ -296,7 +297,24 @@ describe("IndexModuleService query", function () {
},
})
const { data: dataNot } = await module.query({
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
filters: {
product: {
variants: {
sku: {
$not: {
$eq: null,
},
},
},
},
},
})
expect(data.length).toEqual(1)
expect(dataNot.length).toEqual(1)
expect(dataNot).toEqual(data)
const { data: data2 } = await module.query({
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
@@ -340,6 +358,7 @@ describe("IndexModuleService query", function () {
},
{
id: "prod_1",
title: "Product 1",
variants: [
{
id: "var_2",
@@ -399,6 +418,7 @@ describe("IndexModuleService query", function () {
},
{
id: "prod_1",
title: "Product 1",
variants: [
{
id: "var_2",
@@ -456,6 +476,7 @@ describe("IndexModuleService query", function () {
},
{
id: "prod_1",
title: "Product 1",
variants: [
{
id: "var_1",
@@ -499,6 +520,7 @@ describe("IndexModuleService query", function () {
expect(dataAsc).toEqual([
{
id: "prod_1",
title: "Product 1",
variants: [
{
id: "var_2",
@@ -597,6 +619,7 @@ describe("IndexModuleService query", function () {
expect(data).toEqual([
{
id: "prod_1",
title: "Product 1",
variants: [
{
id: "var_1",
@@ -646,6 +669,7 @@ describe("IndexModuleService query", function () {
expect(data).toEqual([
{
id: "prod_1",
title: "Product 1",
variants: [
{
id: "var_1",
@@ -782,6 +806,7 @@ describe("IndexModuleService query", function () {
expect(data).toEqual([
{
id: "prod_1",
title: "Product 1",
variants: [
{
id: "var_1",
@@ -922,6 +947,7 @@ describe("IndexModuleService query", function () {
expect(data).toEqual([
{
id: "prod_1",
title: "Product 1",
variants: [
{
id: "var_1",
@@ -937,4 +963,165 @@ describe("IndexModuleService query", function () {
},
])
})
it("should query products filtering product not in [X]", async () => {
const expected = [
{
id: "prod_2",
title: "Product 2 title",
deep: {
a: 1,
obj: {
b: 15,
},
},
},
]
const { data } = await module.query({
fields: ["product.*"],
filters: {
product: {
$not: [
{
id: {
$in: ["prod_1"],
},
},
],
},
},
})
expect(data).toEqual(expected)
})
it("should query products filtering product not in [X] using $nin", async () => {
const expected = [
{
id: "prod_2",
title: "Product 2 title",
deep: {
a: 1,
obj: {
b: 15,
},
},
},
]
const { data } = await module.query({
fields: ["product.*"],
filters: {
product: {
id: {
$nin: ["prod_1"],
},
},
},
})
expect(data).toEqual(expected)
})
it("should query products with variants.sku not in [X] and title eq", async () => {
const expected = [
{
id: "prod_2",
title: "Product 2 title",
deep: {
a: 1,
obj: {
b: 15,
},
},
},
]
const { data } = await module.query({
fields: ["product.*", "variants.*"],
filters: {
product: {
variants: {
sku: {
$nin: ["sku 123"],
},
},
title: {
$eq: "Product 2 title",
},
},
},
})
expect(data).toEqual(expected)
})
it("should query products filtering title like and not equal specific value", async () => {
const expected = [
{
id: "prod_2",
title: "Product 2 title",
deep: {
a: 1,
obj: {
b: 15,
},
},
},
]
const { data } = await module.query({
fields: ["product.*"],
filters: {
product: {
$and: [
{
title: {
$like: "Product%",
},
},
{
$not: {
title: {
$eq: "Product 1",
},
},
},
],
},
},
})
expect(data).toEqual(expected)
})
it("should query products filtering title using $ilike", async () => {
const expected = [
{
id: "prod_2",
title: "Product 2 title",
},
]
const { data } = await module.query({
fields: ["product.id", "product.title"],
filters: {
product: {
title: {
$ilike: "PROdUCt 2%",
},
},
},
})
expect(data).toEqual(expected)
const { data: sensitive } = await module.query({
fields: ["product.id", "product.title"],
filters: {
product: {
title: {
$like: "PROdUCt 2%",
},
},
},
})
expect(sensitive).toEqual([])
})
})