Merge pull request #34190 from backstage/freben/facets-count-optimization

fix(catalog-backend): simplify facets COUNT(DISTINCT) to COUNT(*)
This commit is contained in:
Fredrik Adelöw
2026-05-12 15:32:08 +02:00
committed by GitHub
3 changed files with 28 additions and 22 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Simplified the entity facets aggregation from `COUNT(DISTINCT entity_id)` to `COUNT(*)`. The unique constraint on `(entity_id, key, value)` guarantees each entity appears at most once per search row group, making the `DISTINCT` unnecessary. This allows the database to use a simpler aggregation plan.
@@ -2549,18 +2549,18 @@ describe('DefaultEntitiesCatalog', () => {
},
]);
await expect(
catalog.facets({
facets: ['spec.type'],
query: { kind: 'component' },
credentials: mockCredentials.none(),
}),
).resolves.toEqual({
const result = await catalog.facets({
facets: ['spec.type'],
query: { kind: 'component' },
credentials: mockCredentials.none(),
});
expect(result.facets['spec.type']).toHaveLength(2);
expect(result).toEqual({
facets: {
'spec.type': [
'spec.type': expect.arrayContaining([
{ value: 'library', count: 1 },
{ value: 'service', count: 1 },
],
]),
},
});
},
@@ -2590,18 +2590,18 @@ describe('DefaultEntitiesCatalog', () => {
},
]);
await expect(
catalog.facets({
facets: ['kind'],
query: { kind: { $in: ['component', 'api'] } },
credentials: mockCredentials.none(),
}),
).resolves.toEqual({
const result = await catalog.facets({
facets: ['kind'],
query: { kind: { $in: ['component', 'api'] } },
credentials: mockCredentials.none(),
});
expect(result.facets.kind).toHaveLength(2);
expect(result).toEqual({
facets: {
kind: [
kind: expect.arrayContaining([
{ value: 'API', count: 1 },
{ value: 'Component', count: 1 },
],
]),
},
});
},
@@ -2687,10 +2687,10 @@ describe('DefaultEntitiesCatalog', () => {
}),
).resolves.toEqual({
facets: {
'metadata.name': [
'metadata.name': expect.arrayContaining([
{ value: 'one', count: 1 },
{ value: 'two', count: 1 },
],
]),
},
});
},
@@ -691,9 +691,10 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog {
.select({
facet: 'search.key',
value: 'search.original_value',
count: this.database.raw('count(DISTINCT search.entity_id)'),
count: this.database.raw('count(*)'),
})
.groupBy(['search.key', 'search.original_value']);
.groupBy(['search.key', 'search.original_value'])
.orderBy(['search.key', 'search.original_value']);
if (request.filter || request.query) {
// Build a subquery that finds matching entity IDs via