From c3d1c25dcd8b5c85c4de639e5cbf55a367c644b5 Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 11:41:20 -0400 Subject: [PATCH 01/10] add placeholder --- modules/server/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/server/README.md b/modules/server/README.md index 4d25ba4d2..9f853040f 100644 --- a/modules/server/README.md +++ b/modules/server/README.md @@ -21,6 +21,8 @@ npm run prepare ## Federated Search +[Placeholder] + ### Config -[Placeholder] +[Placeholder] From 9d6fe98953480be1ed98ae70dbd27907d611915a Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 11:45:03 -0400 Subject: [PATCH 02/10] Adjust config template example and file --- modules/server/configTemplates/configs.json.schema | 9 +++++++++ modules/server/configTemplates/network.json | 8 +------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/modules/server/configTemplates/configs.json.schema b/modules/server/configTemplates/configs.json.schema index 1147f2b45..796db2b1b 100644 --- a/modules/server/configTemplates/configs.json.schema +++ b/modules/server/configTemplates/configs.json.schema @@ -73,4 +73,13 @@ "maxResultsWindow": 10000, "rowIdFieldName": "analysis.analysis_id" } + "network": { + "servers": [ + { + "displayName": "Toronto", + "graphqlUrl": "http:///graphql", + "documentType": "file" + } + ] + } } diff --git a/modules/server/configTemplates/network.json b/modules/server/configTemplates/network.json index 60dfdbf46..8da288b9c 100644 --- a/modules/server/configTemplates/network.json +++ b/modules/server/configTemplates/network.json @@ -1,11 +1,5 @@ { "network": { - "servers": [ - { - "displayName": "Toronto", - "graphqlUrl": "http://.../graphql", - "documentType": "file" - } - ] + "servers": [] } } From f1e4666c5b3ccfeb91289b593d6aaf2c3b668a7e Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 12:20:18 -0400 Subject: [PATCH 03/10] remove unused arranger constructor param --- modules/server/src/app.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/server/src/app.js b/modules/server/src/app.js index aa392e773..3383b252f 100644 --- a/modules/server/src/app.js +++ b/modules/server/src/app.js @@ -12,11 +12,9 @@ export default async function (rootPath = '') { /** * @param {boolean} enableAdmin - * @param {boolean} enableDocumentHits - enables including "hits" property in the GQL response */ return arranger({ enableAdmin: ENV_CONFIG.ENABLE_ADMIN, - enableDocumentHits: ENV_CONFIG.ENABLE_DOCUMENT_HITS, }).then((router) => { app.use(router); From d36c021e849190ffc4f14b06adf475d0e60603dd Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 12:22:26 -0400 Subject: [PATCH 04/10] reorder constants file, parse env var --- modules/server/src/config/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/server/src/config/constants.ts b/modules/server/src/config/constants.ts index e3f7c6c2c..3b6c860f3 100644 --- a/modules/server/src/config/constants.ts +++ b/modules/server/src/config/constants.ts @@ -5,7 +5,7 @@ export const ALLOW_CUSTOM_MAX_DOWNLOAD_ROWS = stringToBool( ); export const CONFIG_FILES_PATH = process.env.CONFIG_PATH || './configs'; export const DATA_MASK_MIN_THRESHOLD = - process.env.DATA_MASK_MIN_THRESHOLD || Number.MAX_SAFE_INTEGER; + stringToNumber(process.env.DATA_MASK_MIN_THRESHOLD) || Number.MAX_SAFE_INTEGER; export const DEBUG_MODE = stringToBool(process.env.DEBUG); export const DOCUMENT_TYPE = process.env.DOCUMENT_TYPE || ''; export const DOWNLOAD_STREAM_BUFFER_SIZE = @@ -13,6 +13,7 @@ export const DOWNLOAD_STREAM_BUFFER_SIZE = export const ENABLE_ADMIN = stringToBool(process.env.ENABLE_ADMIN); export const ENABLE_DOCUMENT_HITS = stringToBool(process.env.ENABLE_DOCUMENT_HITS); export const ENABLE_LOGS = stringToBool(process.env.ENABLE_LOGS); +export const ENABLE_NETWORK_AGGREGATION = stringToBool(process.env.ENABLE_NETWORK_AGGREGATION); export const ES_ARRANGER_SET_INDEX = process.env.ES_ARRANGER_SET_INDEX || 'arranger-sets'; export const ES_ARRANGER_SET_TYPE = process.env.ES_ARRANGER_SET_TYPE || 'arranger-sets'; export const ES_HOST = process.env.ES_HOST || 'http://127.0.0.1:9200'; @@ -27,4 +28,3 @@ export const PING_MS = stringToNumber(process.env.PING_MS) || 2200; export const PING_PATH = process.env.PING_PATH || '/ping'; export const PORT = stringToNumber(process.env.PORT) || 5050; export const ROW_ID_FIELD_NAME = process.env.ROW_ID_FIELD_NAME || 'id'; -export const ENABLE_NETWORK_AGGREGATION = stringToBool(process.env.ENABLE_NETWORK_AGGREGATION); From 4d00dde4e5d2404e890a5f042aed628813d791cf Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 12:34:49 -0400 Subject: [PATCH 05/10] update arranger network config type --- modules/server/src/config/types.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/server/src/config/types.ts b/modules/server/src/config/types.ts index 7f16e3fef..e152791e7 100644 --- a/modules/server/src/config/types.ts +++ b/modules/server/src/config/types.ts @@ -1,7 +1,6 @@ // TODO: will gradually tighten these as we migrate to TS import { ES_TYPES } from '@/mapping/esToAggTypeMap'; -import { DOCUMENT_TYPE } from './constants'; export const ConfigOptionalProperties = { DOWNLOADS: 'downloads', @@ -55,7 +54,7 @@ export const TableProperties = { ROW_ID_FIELD_NAME: 'rowIdFieldName', } as const; -export const NetworkAggregationProperties = { +const NetworkAggregationProperties = { GRAPHQL_URL: 'graphqlUrl', DOCUMENT_TYPE: 'documentType', DISPLAY_NAME: 'displayName', @@ -151,10 +150,12 @@ export interface TableConfigsInterface { [ConfigProperties.ROW_ID_FIELD_NAME]?: string; } -export interface NetworkAggregationInterface { - [NetworkAggregationProperties.GRAPHQL_URL]: string; - [NetworkAggregationProperties.DOCUMENT_TYPE]: string; - [NetworkAggregationProperties.DISPLAY_NAME]: string; +interface NetworkAggregationInterface { + servers: { + [NetworkAggregationProperties.GRAPHQL_URL]: string; + [NetworkAggregationProperties.DOCUMENT_TYPE]: string; + [NetworkAggregationProperties.DISPLAY_NAME]: string; + }[]; } export interface ConfigObject { @@ -165,7 +166,7 @@ export interface ConfigObject { [ConfigProperties.INDEX]: string; [ConfigProperties.MATCHBOX]: any[]; [ConfigProperties.TABLE]: TableConfigsInterface; - [ConfigProperties.NETWORK_AGGREGATION]: NetworkAggregationInterface[]; + [ConfigProperties.NETWORK_AGGREGATION]: NetworkAggregationInterface; } export interface FieldFromMapping { From 0d22b370aaff6eeedb55170d1cb995edae248017 Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 12:50:12 -0400 Subject: [PATCH 06/10] type, add gql server types --- modules/server/src/gqlServer.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 modules/server/src/gqlServer.ts diff --git a/modules/server/src/gqlServer.ts b/modules/server/src/gqlServer.ts new file mode 100644 index 000000000..83f93cc23 --- /dev/null +++ b/modules/server/src/gqlServer.ts @@ -0,0 +1,24 @@ +import { Client } from '@elastic/elasticsearch'; +import { GraphQLResolveInfo } from 'graphql'; + +export type Context = { + esClient: Client; +}; + +export type ResolverOutput = T | Promise; + +/** + * GQL resolver + * + * @param root - Parent object of a query. + * @param args - Query arguments. + * @param context - Context passed to apollo-server for queries. + * @param info - GraphQL info object. + * @return Returns resolved value; + */ +export type Resolver = ( + root: Root, + args: QueryArgs, + context: Context, + info: GraphQLResolveInfo, +) => ResolverOutput | ResolverOutput; From b00e5b282e8948c1527a3f28e182704faca262fc Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 12:59:25 -0400 Subject: [PATCH 07/10] graphqlRoutes, remove unused import, export func --- modules/server/src/graphqlRoutes.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/server/src/graphqlRoutes.js b/modules/server/src/graphqlRoutes.js index f980ec6c7..c737abcb6 100644 --- a/modules/server/src/graphqlRoutes.js +++ b/modules/server/src/graphqlRoutes.js @@ -5,7 +5,7 @@ import expressPlayground from 'graphql-playground-middleware-express'; import { mergeSchemas } from '@graphql-tools/schema'; import getConfigObject, { initializeSets } from './config'; -import { DEBUG_MODE, ENABLE_NETWORK_AGGREGATION, ES_PASS, ES_USER } from './config/constants'; +import { DEBUG_MODE, ES_PASS, ES_USER } from './config/constants'; import { ConfigProperties } from './config/types'; import { addMappingsToTypes, extendFields, fetchMapping } from './mapping'; import { extendColumns, extendFacets, flattenMappingToFields } from './mapping/extendMapping'; @@ -243,7 +243,7 @@ const createEndpoint = async ({ esClient, graphqlOptions = {}, mockSchema, schem return router; }; -const createSchemasFromConfigs = async ({ +export const createSchemasFromConfigs = async ({ configsSource = '', enableAdmin, enableDocumentHits, @@ -272,7 +272,7 @@ const createSchemasFromConfigs = async ({ const schemasToMerge = [schema]; - /* + /** * Federated Network Search */ if (enableNetworkAggregation) { From 2268f85ad612e92268bf83a7f7b5eb653151182b Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 15:02:03 -0400 Subject: [PATCH 08/10] resolver creation, improve TS usage, split functionality into distinct files, improve usage' --- .../src/mapping/createConnectionTypeDefs.js | 21 ++-- modules/server/src/mapping/mappingToFields.js | 3 +- modules/server/src/mapping/masking.ts | 2 +- ...Aggregations.js => resolveAggregations.ts} | 50 ++++++++-- .../server/src/mapping/resolveHitsFromAggs.ts | 51 ++++++++++ modules/server/src/mapping/resolvers.ts | 95 ++++--------------- modules/server/src/mapping/types.ts | 9 +- 7 files changed, 135 insertions(+), 96 deletions(-) rename modules/server/src/mapping/{resolveAggregations.js => resolveAggregations.ts} (59%) create mode 100644 modules/server/src/mapping/resolveHitsFromAggs.ts diff --git a/modules/server/src/mapping/createConnectionTypeDefs.js b/modules/server/src/mapping/createConnectionTypeDefs.js index a0e4da932..132694297 100644 --- a/modules/server/src/mapping/createConnectionTypeDefs.js +++ b/modules/server/src/mapping/createConnectionTypeDefs.js @@ -1,8 +1,17 @@ import mappingToAggsType from './mappingToAggsType'; -export default ({ type, fields = '', createStateTypeDefs = true, showRecords }) => { - const dataMaskingType = !showRecords ? 'type DataMasking { thresholdValue: Int }' : ''; +const createConnectionType = (enableDocumentHits) => { + return `type ${type.name}Connection { + total: Int! + ${enableDocumentHits ? `edges: [${type.name}Edge]` : ''} + }`; +}; + +const createDataMaskingType = (enableDocumentHits) => { + return !enableDocumentHits ? `type DataMasking { thresholdValue: Int }` : ''; +}; +export default ({ type, fields = '', createStateTypeDefs = true, enableDocumentHits }) => { return ` type ${type.name} { aggregations( @@ -34,12 +43,10 @@ export default ({ type, fields = '', createStateTypeDefs = true, showRecords }) ${mappingToAggsType(type.mapping)} } - ${dataMaskingType} + ${createDataMaskingType(enableDocumentHits)} - type ${type.name}Connection { - total: Int! - ${showRecords ? `edges: [${type.name}Edge]` : ''} - } + ${createConnectionType(enableDocumentHits)} + type ${type.name}Edge { searchAfter: JSON diff --git a/modules/server/src/mapping/mappingToFields.js b/modules/server/src/mapping/mappingToFields.js index d2899d6ed..86546585f 100644 --- a/modules/server/src/mapping/mappingToFields.js +++ b/modules/server/src/mapping/mappingToFields.js @@ -6,7 +6,6 @@ import mappingToObjectTypes from './mappingToObjectTypes'; import mappingToScalarFields from './mappingToScalarFields'; const mappingToFields = ({ enableDocumentHits, type, parent }) => { - const showRecords = enableDocumentHits; return [ mappingToObjectTypes(type.name, type.mapping, parent, type.extendedFields), Object.entries(type.mapping) @@ -29,7 +28,7 @@ const mappingToFields = ({ enableDocumentHits, type, parent }) => { type.customFields, ], createStateTypeDefs: 'createState' in type ? type.createState : true, - showRecords, + enableDocumentHits, }), ].join(); }; diff --git a/modules/server/src/mapping/masking.ts b/modules/server/src/mapping/masking.ts index 4229a094a..d1b8be41e 100644 --- a/modules/server/src/mapping/masking.ts +++ b/modules/server/src/mapping/masking.ts @@ -8,7 +8,7 @@ export const Relation = { export type Relation = keyof typeof Relation; /** - * This returns a total count that is less than or equal to the actual total hits in the query. + * Returns a total count that is less than or equal to the actual total hits in the query * It is calculated by adding +1 for values under threshold or adding bucket.doc_count amount * for values greater than or equal to * diff --git a/modules/server/src/mapping/resolveAggregations.js b/modules/server/src/mapping/resolveAggregations.ts similarity index 59% rename from modules/server/src/mapping/resolveAggregations.js rename to modules/server/src/mapping/resolveAggregations.ts index aeb4b2d0c..6fe5194e6 100644 --- a/modules/server/src/mapping/resolveAggregations.js +++ b/modules/server/src/mapping/resolveAggregations.ts @@ -2,12 +2,48 @@ import getFields from 'graphql-fields'; import { buildAggregations, buildQuery, flattenAggregations } from '../middleware'; +import { Resolver } from '@/gqlServer'; +import { GetServerSideFilterFn } from '@/utils/getDefaultServerSideFilter'; import { resolveSetsInSqon } from './hackyTemporaryEsSetResolution'; +import { Relation } from './masking'; +import { AggregationQuery, Root } from './types'; import compileFilter from './utils/compileFilter'; import esSearch from './utils/esSearch'; -export default ({ type, getServerSideFilter }) => { - return async ( +const toGraphqlField = (acc: Aggregations, [a, b]: [string, Aggregation]) => ({ + ...acc, + [a.replace(/\./g, '__')]: b, +}); +export const aggregationsToGraphql = (aggregations: Aggregations) => { + return Object.entries(aggregations).reduce(toGraphqlField, {}); +}; + +/* + * Types + */ +export type Bucket = { + doc_count: number; + key: string; + relation: Relation; +}; + +export type Aggregation = { + bucket_count: number; + buckets: Bucket[]; +}; + +export type Aggregations = Record; + +export type AggregationsResolver = Resolver>; + +const getAggregationsResolver = ({ + type, + getServerSideFilter, +}: { + type: Record; + getServerSideFilter: GetServerSideFilterFn | undefined; +}) => { + const resolver: Resolver> = async ( obj, { filters, aggregations_filter_themselves, include_missing = true }, context, @@ -26,7 +62,7 @@ export default ({ type, getServerSideFilter }) => { nestedFieldNames, filters: compileFilter({ clientSideFilter: resolvedFilter, - serverSideFilter: getServerSideFilter(context), + serverSideFilter: getServerSideFilter && getServerSideFilter(), }), }); @@ -48,6 +84,7 @@ export default ({ type, getServerSideFilter }) => { const response = await esSearch(esClient)({ index: type.index, size: 0, + // @ts-expect-error - valid search query parameter in ES 7.17, not in types _source: false, body, }); @@ -58,9 +95,8 @@ export default ({ type, getServerSideFilter }) => { return aggregations; }; -}; -const toGraphqlField = (acc, [a, b]) => ({ ...acc, [a.replace(/\./g, '__')]: b }); -export const aggregationsToGraphql = (aggregations) => { - return Object.entries(aggregations).reduce(toGraphqlField, {}); + return resolver; }; + +export default getAggregationsResolver; diff --git a/modules/server/src/mapping/resolveHitsFromAggs.ts b/modules/server/src/mapping/resolveHitsFromAggs.ts new file mode 100644 index 000000000..b12a0d9d6 --- /dev/null +++ b/modules/server/src/mapping/resolveHitsFromAggs.ts @@ -0,0 +1,51 @@ +import { Resolver } from '@/gqlServer'; +import { get } from 'lodash'; +import { applyAggregationMasking } from './masking'; +import { AggregationsResolver } from './resolveAggregations'; +import { HitsQuery, Root } from './types'; + +type HitsResolver = Resolver>; + +/** + * Resolver for "aggregation only mode" of Arranger where "hits" is based on "aggregations" + * Calculate hits from aggregation data, instead of using "hits" ES response field + * + * If "aggregations" field is not in query, return 0 + * + * @param aggregationsResolver - resolver ES query code for aggregations + * @returns Returns a total count that is less than or equal to the actual total hits in the query. + */ +export const getHitsFromAggsResolver = (aggregationsResolver: AggregationsResolver) => { + const resolver: HitsResolver = async (obj, args, context, info) => { + /* + * Get "aggregations" field from full query if found + * Popular gql parsing libs parse the "info" property which may not include full query based on schema + */ + const aggregationsPath = 'operation.selectionSet.selections[0].selectionSet.selections'; + const aggregationsSelectionSet = get(info, aggregationsPath, []).find( + (selection: { kind: string; name: { value: string } }) => + selection.kind === 'Field' && selection.name.value === 'aggregations', + ); + + if (aggregationsSelectionSet) { + const modifiedInfo = { ...info, fieldNodes: [aggregationsSelectionSet] }; + + const aggregations = await aggregationsResolver( + obj, + // @ts-ignore + // modifying the query info field inline so it can query aggregations correctly + // not idiomatic so doesn't line up with typings from graphql + info.variableValues, + context, + modifiedInfo, + ); + const { hitsTotal: total } = applyAggregationMasking({ + aggregations, + }); + return { total }; + } else { + return { total: 0 }; + } + }; + return resolver; +}; diff --git a/modules/server/src/mapping/resolvers.ts b/modules/server/src/mapping/resolvers.ts index 9b7e61b00..dc78f0f42 100644 --- a/modules/server/src/mapping/resolvers.ts +++ b/modules/server/src/mapping/resolvers.ts @@ -1,61 +1,13 @@ import { ConfigProperties, ExtendedConfigsInterface } from '@/config/types'; -import { GraphQLResolveInfo } from 'graphql'; -import { get } from 'lodash'; import { CreateConnectionResolversArgs } from './createConnectionResolvers'; import { applyAggregationMasking } from './masking'; -import resolveAggregations, { aggregationsToGraphql } from './resolveAggregations'; +import getAggregationsResolver, { + AggregationsResolver, + aggregationsToGraphql, +} from './resolveAggregations'; import resolveHits from './resolveHits'; -import { Aggregation, Context, Hits, Root } from './types'; - -/** - * Resolve hits from aggregations - * If "aggregations" field is not in query, return 0 - * - * @param aggregationsQuery - resolver ES query code for aggregations - * @returns Returns a total count that is less than or equal to the actual total hits in the query. - */ -const resolveHitsFromAggs = - ( - aggregationsQuery: ( - obj: Root, - args: { - filters?: object; - include_missing?: boolean; - aggregations_filter_themselves?: boolean; - }, - context: Context, - info: GraphQLResolveInfo, - ) => Record, - ) => - async (obj: Root, args: Hits, context: Context, info: GraphQLResolveInfo) => { - /* - * Get "aggregations" field from full query if found - * Popular gql parsing libs parse the "info" property which may not include full query based on schema - */ - const aggregationsPath = 'operation.selectionSet.selections[0].selectionSet.selections'; - const aggregationsSelectionSet = get(info, aggregationsPath, []).find( - (selection: { kind: string; name: { value: string } }) => - selection.kind === 'Field' && selection.name.value === 'aggregations', - ); - - /* - * This function is used for "aggregation only mode" of Arranger where "hits" is based on "aggregations" - * A user might request only the "hits" field in a GQL query, in which case return 0 - */ - if (aggregationsSelectionSet) { - const modifiedInfo = { ...info, fieldNodes: [aggregationsSelectionSet] }; - // @ts-ignore - // modifying the query info field inline so it can query aggregations correctly - // not idiomatic so doesn't line up with typings from graphql - const aggregations = await aggregationsQuery(obj, info.variableValues, context, modifiedInfo); - const { hitsTotal: total, dataMaskedAggregations } = applyAggregationMasking({ - aggregations, - }); - return { total }; - } else { - return { total: 0 }; - } - }; +import { getHitsFromAggsResolver } from './resolveHitsFromAggs'; +import { Root } from './types'; export const createResolvers = ({ createStateResolvers, @@ -65,7 +17,7 @@ export const createResolvers = ({ enableDocumentHits, }: Omit) => { // configs - const configs = async (parentObj: Root, { fieldNames }: { fieldNames: string[] }) => { + const configs = async (_unusedParentObj: Root, { fieldNames }: { fieldNames: string[] }) => { return { downloads: type.config?.[ConfigProperties.DOWNLOADS], extended: fieldNames @@ -81,20 +33,14 @@ export const createResolvers = ({ }; }; - // aggregations - const aggregationsQuery = resolveAggregations({ type, getServerSideFilter }); + /** + * aggregations + * return resolver with document hits or data masking applied + */ + const aggregationsResolver = getAggregationsResolver({ type, getServerSideFilter }); - const aggregations = async ( - obj: Root, - args: { - filters: object; - include_missing: boolean; - aggregations_filter_themselves: boolean; - }, - context: Context, - info: GraphQLResolveInfo, - ) => { - const aggregations = await aggregationsQuery(obj, args, context, info); + const aggregations: AggregationsResolver = async (obj, args, context, info) => { + const aggregations = await aggregationsResolver(obj, args, context, info); if (enableDocumentHits) { return aggregationsToGraphql(aggregations); } else { @@ -105,14 +51,13 @@ export const createResolvers = ({ } }; - // hits - const defaultHitsResolver = resolveHits({ type, Parallel, getServerSideFilter }); + /** + * hits + * return resolver with hits from ES or hits calculated from aggregations + */ const hits = enableDocumentHits - ? defaultHitsResolver - : // @ts-ignore - // typing resolveAggregations requires typing a lot of code down the chain - // TODO: improve typing - resolveHitsFromAggs(aggregationsQuery); + ? resolveHits({ type, Parallel, getServerSideFilter }) + : getHitsFromAggsResolver(aggregationsResolver); return { hits, aggregations, configs }; }; diff --git a/modules/server/src/mapping/types.ts b/modules/server/src/mapping/types.ts index 5c2ffad5a..0972f5e90 100644 --- a/modules/server/src/mapping/types.ts +++ b/modules/server/src/mapping/types.ts @@ -1,4 +1,3 @@ -import { Client } from '@elastic/elasticsearch'; import { Relation } from './masking'; export type Bucket = { @@ -38,7 +37,7 @@ export type Sort = { missing: Missing; }; -export type Hits = { +export type HitsQuery = { score: string; offset: number; sort: [Sort]; @@ -51,6 +50,8 @@ export type Hits = { trackTotalHits: boolean; }; -export type Context = { - es: Client; +export type AggregationQuery = { + filters: any; + aggregations_filter_themselves: boolean; + include_missing: boolean; }; From 77d4e59d1e3892d5df0d01afc89dee128a51a252 Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 15:06:42 -0400 Subject: [PATCH 09/10] add surrounding brackets for func --- modules/server/src/mapping/utils/esSearch.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/server/src/mapping/utils/esSearch.ts b/modules/server/src/mapping/utils/esSearch.ts index 51cfdd712..1b4a5460a 100644 --- a/modules/server/src/mapping/utils/esSearch.ts +++ b/modules/server/src/mapping/utils/esSearch.ts @@ -1,4 +1,5 @@ import { Client, RequestParams } from '@elastic/elasticsearch'; -export default (esClient: Client) => async (params: RequestParams.Search) => - (await esClient?.search(params))?.body; +export default (esClient: Client) => async (params: RequestParams.Search) => { + return (await esClient?.search(params))?.body; +}; From 2eb1e5c09b8e6f2e7c50831e6c111f779d9687f2 Mon Sep 17 00:00:00 2001 From: Ciaran Schutte Date: Fri, 14 Mar 2025 16:22:55 -0400 Subject: [PATCH 10/10] cleanup schema resolvers --- modules/server/src/schema/Aggregations.ts | 7 +------ modules/server/src/schema/Root.js | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/modules/server/src/schema/Aggregations.ts b/modules/server/src/schema/Aggregations.ts index ad5f6b034..eaa9649df 100644 --- a/modules/server/src/schema/Aggregations.ts +++ b/modules/server/src/schema/Aggregations.ts @@ -1,9 +1,4 @@ -/** - * - * @param enableDocumentHits if false, agg only mode is enabled, add to GQL schema definition - * @returns typedef string - */ -export const typeDefs = ({ enableDocumentHits }: { enableDocumentHits: boolean }) => ` +export const typeDefs = ` type Stats { max: Float min: Float diff --git a/modules/server/src/schema/Root.js b/modules/server/src/schema/Root.js index 5e1d45918..d5e3fed77 100644 --- a/modules/server/src/schema/Root.js +++ b/modules/server/src/schema/Root.js @@ -65,7 +65,7 @@ let RootTypeDefs = ({ types, rootTypes, scalarTypes }) => ` export let typeDefs = ({ enableDocumentHits, types, rootTypes, scalarTypes }) => [ RootTypeDefs({ types, rootTypes, scalarTypes }), - AggregationsTypeDefs({ enableDocumentHits }), + AggregationsTypeDefs, SetTypeDefs, SortTypeDefs, ConfigsTypeDefs,