feat: query.index (#11348)
What:
- `query.index` helper. It queries the index module, and aggregate the rest of requested fields/relations if needed like `query.graph`.
Not covered in this PR:
- Hydrate only sub entities returned by the query. Example: 1 out of 5 variants have returned, it should only hydrate the data of the single entity, currently it will merge all the variants of the product.
- Generate types of indexed data
example:
```ts
const query = container.resolve(ContainerRegistrationKeys.QUERY)
await query.index({
entity: "product",
fields: [
"id",
"description",
"status",
"variants.sku",
"variants.barcode",
"variants.material",
"variants.options.value",
"variants.prices.amount",
"variants.prices.currency_code",
"variants.inventory_items.inventory.sku",
"variants.inventory_items.inventory.description",
],
filters: {
"variants.sku": { $like: "%-1" },
"variants.prices.amount": { $gt: 30 },
},
pagination: {
order: {
"variants.prices.amount": "DESC",
},
},
})
```
This query return all products where at least one variant has the title ending in `-1` and at least one price bigger than `30`.
The Index Module only hold the data used to paginate and filter, and the returned object is:
```json
{
"id": "prod_01JKEAM2GJZ14K64R0DHK0JE72",
"title": null,
"variants": [
{
"id": "variant_01JKEAM2HC89GWS95F6GF9C6YA",
"sku": "extra-variant-1",
"prices": [
{
"id": "price_01JKEAM2JADEWWX72F8QDP6QXT",
"amount": 80,
"currency_code": "USD"
}
]
}
]
}
```
All the rest of the fields will be hydrated from their respective modules, and the final result will be:
```json
{
"id": "prod_01JKEAY2RJTF8TW9A23KTGY1GD",
"description": "extra description",
"status": "draft",
"variants": [
{
"sku": "extra-variant-1",
"barcode": null,
"material": null,
"id": "variant_01JKEAY2S945CRZ6X4QZJ7GVBJ",
"options": [
{
"value": "Red"
}
],
"prices": [
{
"amount": 20,
"currency_code": "CAD",
"id": "price_01JKEAY2T2EEYSWZHPGG11B7W7"
},
{
"amount": 80,
"currency_code": "USD",
"id": "price_01JKEAY2T2NJK2E5468RK84CAR"
}
],
"inventory_items": [
{
"variant_id": "variant_01JKEAY2S945CRZ6X4QZJ7GVBJ",
"inventory_item_id": "iitem_01JKEAY2SNY2AWEHPZN0DDXVW6",
"inventory": {
"sku": "extra-variant-1",
"description": "extra variant 1",
"id": "iitem_01JKEAY2SNY2AWEHPZN0DDXVW6"
}
}
]
}
]
}
```
Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
This commit is contained in:
co-authored by
Adrien de Peretti
parent
8d10731343
commit
22276648ad
@@ -509,7 +509,7 @@ describe("IndexModuleService query", function () {
|
||||
})
|
||||
|
||||
it("should query products filtering by variant sku", async () => {
|
||||
const { data } = await module.query({
|
||||
const { data, metadata } = await module.query({
|
||||
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
||||
filters: {
|
||||
product: {
|
||||
@@ -518,6 +518,16 @@ describe("IndexModuleService query", function () {
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
take: 100,
|
||||
skip: 0,
|
||||
},
|
||||
})
|
||||
|
||||
expect(metadata).toEqual({
|
||||
count: 1,
|
||||
skip: 0,
|
||||
take: 100,
|
||||
})
|
||||
|
||||
expect(data).toEqual([
|
||||
@@ -539,8 +549,8 @@ describe("IndexModuleService query", function () {
|
||||
])
|
||||
})
|
||||
|
||||
it("should query products filtering by variant sku", async () => {
|
||||
const { data } = await module.query({
|
||||
it("should query products filtering by variant sku and join filters on prices amount", async () => {
|
||||
const { data, metadata } = await module.query({
|
||||
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
||||
joinFilters: {
|
||||
"product.variants.prices.amount": { $gt: 110 },
|
||||
@@ -552,6 +562,16 @@ describe("IndexModuleService query", function () {
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
take: 100,
|
||||
skip: 0,
|
||||
},
|
||||
})
|
||||
|
||||
expect(metadata).toEqual({
|
||||
count: 1,
|
||||
skip: 0,
|
||||
take: 100,
|
||||
})
|
||||
|
||||
expect(data).toEqual([
|
||||
@@ -568,8 +588,45 @@ describe("IndexModuleService query", function () {
|
||||
])
|
||||
})
|
||||
|
||||
it("should query products filtering by price and returning the complete entity", async () => {
|
||||
it("should filter using fields not selected", async () => {
|
||||
const { data } = await module.query({
|
||||
fields: ["product.id", "product.variants.*"],
|
||||
pagination: {
|
||||
order: {
|
||||
product: {
|
||||
variants: {
|
||||
prices: {
|
||||
amount: "DESC",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(data).toEqual([
|
||||
{
|
||||
id: "prod_1",
|
||||
variants: [
|
||||
{
|
||||
id: "var_1",
|
||||
sku: "aaa test aaa",
|
||||
},
|
||||
{
|
||||
id: "var_2",
|
||||
sku: "sku 123",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "prod_2",
|
||||
variants: [],
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it("should query products filtering by price and returning the complete entity", async () => {
|
||||
const { data, metadata } = await module.query({
|
||||
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
||||
filters: {
|
||||
product: {
|
||||
@@ -581,6 +638,16 @@ describe("IndexModuleService query", function () {
|
||||
},
|
||||
},
|
||||
keepFilteredEntities: true,
|
||||
pagination: {
|
||||
take: 100,
|
||||
skip: 0,
|
||||
},
|
||||
})
|
||||
|
||||
expect(metadata).toEqual({
|
||||
count: 1,
|
||||
skip: 0,
|
||||
take: 100,
|
||||
})
|
||||
|
||||
expect(data).toEqual([
|
||||
@@ -658,7 +725,7 @@ describe("IndexModuleService query", function () {
|
||||
})
|
||||
|
||||
it("should paginate products", async () => {
|
||||
const { data } = await module.query({
|
||||
const { data, metadata } = await module.query({
|
||||
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
||||
pagination: {
|
||||
take: 1,
|
||||
@@ -666,6 +733,11 @@ describe("IndexModuleService query", function () {
|
||||
},
|
||||
})
|
||||
|
||||
expect(metadata).toEqual({
|
||||
count: 2,
|
||||
skip: 1,
|
||||
take: 1,
|
||||
})
|
||||
expect(data).toEqual([
|
||||
{
|
||||
id: "prod_2",
|
||||
@@ -682,7 +754,7 @@ describe("IndexModuleService query", function () {
|
||||
})
|
||||
|
||||
it("should handle null values on where clause", async () => {
|
||||
const { data } = await module.query({
|
||||
const { data: data_, metadata } = await module.query({
|
||||
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
||||
filters: {
|
||||
product: {
|
||||
@@ -691,25 +763,69 @@ describe("IndexModuleService query", function () {
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
take: 100,
|
||||
skip: 0,
|
||||
},
|
||||
})
|
||||
|
||||
expect(metadata).toEqual({
|
||||
count: 1,
|
||||
skip: 0,
|
||||
take: 100,
|
||||
})
|
||||
|
||||
expect(data_).toEqual([
|
||||
{
|
||||
id: "prod_2",
|
||||
deep: { a: 1, obj: { b: 15 } },
|
||||
title: "Product 2 title",
|
||||
variants: [],
|
||||
},
|
||||
])
|
||||
|
||||
const { data, metadata: metadata2 } = await module.query({
|
||||
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
||||
filters: {
|
||||
product: {
|
||||
variants: {
|
||||
sku: { $ne: null },
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
take: 100,
|
||||
skip: 0,
|
||||
},
|
||||
})
|
||||
|
||||
expect(metadata2).toEqual({
|
||||
count: 1,
|
||||
skip: 0,
|
||||
take: 100,
|
||||
})
|
||||
|
||||
expect(data).toEqual([
|
||||
{
|
||||
id: "prod_2",
|
||||
title: "Product 2 title",
|
||||
deep: {
|
||||
a: 1,
|
||||
obj: {
|
||||
b: 15,
|
||||
id: "prod_1",
|
||||
variants: [
|
||||
{
|
||||
id: "var_1",
|
||||
sku: "aaa test aaa",
|
||||
prices: [{ id: "money_amount_1", amount: 100 }],
|
||||
},
|
||||
},
|
||||
variants: [],
|
||||
{
|
||||
id: "var_2",
|
||||
sku: "sku 123",
|
||||
prices: [{ id: "money_amount_2", amount: 10 }],
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it("should query products filtering by deep nested levels", async () => {
|
||||
const { data } = await module.query({
|
||||
const { data, metadata } = await module.query({
|
||||
fields: ["product.*"],
|
||||
filters: {
|
||||
product: {
|
||||
@@ -720,8 +836,17 @@ describe("IndexModuleService query", function () {
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
take: 1,
|
||||
skip: 0,
|
||||
},
|
||||
})
|
||||
|
||||
expect(metadata).toEqual({
|
||||
count: 1,
|
||||
skip: 0,
|
||||
take: 1,
|
||||
})
|
||||
expect(data).toEqual([
|
||||
{
|
||||
id: "prod_2",
|
||||
|
||||
Reference in New Issue
Block a user