Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: fix the search in advance search custom properties #19113

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
@Slf4j
public class SchemaFieldExtractor {

private static final Map<String, Map<String, String>> entityFieldsCache =
private static final Map<String, Map<String, FieldDefinition>> entityFieldsCache =
new ConcurrentHashMap<>();

public SchemaFieldExtractor() {
Expand All @@ -55,7 +55,7 @@ private static void initializeEntityFieldsCache() {
Schema mainSchema = loadMainSchema(schemaPath, entityType, schemaUri, schemaClient);

// Extract fields from the schema
Map<String, String> fieldTypesMap = new LinkedHashMap<>();
Map<String, FieldDefinition> fieldTypesMap = new LinkedHashMap<>();
Deque<Schema> processingStack = new ArrayDeque<>();
Set<String> processedFields = new HashSet<>();
extractFieldsFromSchema(mainSchema, "", fieldTypesMap, processingStack, processedFields);
Expand All @@ -75,7 +75,7 @@ public List<FieldDefinition> extractFields(Type typeEntity, String entityType) {
SchemaClient schemaClient = new CustomSchemaClient(schemaUri);
Deque<Schema> processingStack = new ArrayDeque<>();
Set<String> processedFields = new HashSet<>();
Map<String, String> fieldTypesMap = entityFieldsCache.get(entityType);
Map<String, FieldDefinition> fieldTypesMap = entityFieldsCache.get(entityType);
addCustomProperties(
typeEntity, schemaUri, schemaClient, fieldTypesMap, processingStack, processedFields);
return convertMapToFieldList(fieldTypesMap);
Expand All @@ -90,7 +90,7 @@ public Map<String, List<FieldDefinition>> extractAllCustomProperties(
SchemaClient schemaClient = new CustomSchemaClient(schemaUri);
EntityUtil.Fields fieldsParam = new EntityUtil.Fields(Set.of("customProperties"));
Type typeEntity = repository.getByName(uriInfo, entityType, fieldsParam, Include.ALL, false);
Map<String, String> fieldTypesMap = new LinkedHashMap<>();
Map<String, FieldDefinition> fieldTypesMap = new LinkedHashMap<>();
Set<String> processedFields = new HashSet<>();
Deque<Schema> processingStack = new ArrayDeque<>();
addCustomProperties(
Expand Down Expand Up @@ -170,7 +170,7 @@ private static Schema loadMainSchema(
private static void extractFieldsFromSchema(
Schema schema,
String parentPath,
Map<String, String> fieldTypesMap,
Map<String, FieldDefinition> fieldTypesMap,
Deque<Schema> processingStack,
Set<String> processedFields) {
if (processingStack.contains(schema)) {
Expand Down Expand Up @@ -206,7 +206,8 @@ private static void extractFieldsFromSchema(
arraySchema, fullFieldName, fieldTypesMap, processingStack, processedFields);
} else {
String fieldType = mapSchemaTypeToSimpleType(fieldSchema);
fieldTypesMap.putIfAbsent(fullFieldName, fieldType);
fieldTypesMap.putIfAbsent(
fullFieldName, new FieldDefinition(fullFieldName, fieldType, null));
processedFields.add(fullFieldName);
LOG.debug("Added field '{}', Type: '{}'", fullFieldName, fieldType);
// Recursively process nested objects or arrays
Expand All @@ -220,7 +221,7 @@ private static void extractFieldsFromSchema(
handleArraySchema(arraySchema, parentPath, fieldTypesMap, processingStack, processedFields);
} else {
String fieldType = mapSchemaTypeToSimpleType(schema);
fieldTypesMap.putIfAbsent(parentPath, fieldType);
fieldTypesMap.putIfAbsent(parentPath, new FieldDefinition(parentPath, fieldType, null));
LOG.debug("Added field '{}', Type: '{}'", parentPath, fieldType);
}
} finally {
Expand All @@ -231,15 +232,16 @@ private static void extractFieldsFromSchema(
private static void handleReferenceSchema(
ReferenceSchema referenceSchema,
String fullFieldName,
Map<String, String> fieldTypesMap,
Map<String, FieldDefinition> fieldTypesMap,
Deque<Schema> processingStack,
Set<String> processedFields) {

String refUri = referenceSchema.getReferenceValue();
String referenceType = determineReferenceType(refUri);

if (referenceType != null) {
fieldTypesMap.putIfAbsent(fullFieldName, referenceType);
fieldTypesMap.putIfAbsent(
fullFieldName, new FieldDefinition(fullFieldName, referenceType, null));
processedFields.add(fullFieldName);
LOG.debug("Added field '{}', Type: '{}'", fullFieldName, referenceType);
if (referenceType.startsWith("array<") && referenceType.endsWith(">")) {
Expand All @@ -255,7 +257,7 @@ private static void handleReferenceSchema(
referredSchema, fullFieldName, fieldTypesMap, processingStack, processedFields);
}
} else {
fieldTypesMap.putIfAbsent(fullFieldName, "object");
fieldTypesMap.putIfAbsent(fullFieldName, new FieldDefinition(fullFieldName, "object", null));
processedFields.add(fullFieldName);
LOG.debug("Added field '{}', Type: 'object'", fullFieldName);
extractFieldsFromSchema(
Expand All @@ -270,7 +272,7 @@ private static void handleReferenceSchema(
private static void handleArraySchema(
ArraySchema arraySchema,
String fullFieldName,
Map<String, String> fieldTypesMap,
Map<String, FieldDefinition> fieldTypesMap,
Deque<Schema> processingStack,
Set<String> processedFields) {

Expand All @@ -282,7 +284,8 @@ private static void handleArraySchema(

if (itemsReferenceType != null) {
String arrayFieldType = "array<" + itemsReferenceType + ">";
fieldTypesMap.putIfAbsent(fullFieldName, arrayFieldType);
fieldTypesMap.putIfAbsent(
fullFieldName, new FieldDefinition(fullFieldName, arrayFieldType, null));
processedFields.add(fullFieldName);
LOG.debug("Added field '{}', Type: '{}'", fullFieldName, arrayFieldType);
Schema referredItemsSchema = itemsReferenceSchema.getReferredSchema();
Expand All @@ -292,7 +295,8 @@ private static void handleArraySchema(
}
}
String arrayType = mapSchemaTypeToSimpleType(itemsSchema);
fieldTypesMap.putIfAbsent(fullFieldName, "array<" + arrayType + ">");
fieldTypesMap.putIfAbsent(
fullFieldName, new FieldDefinition(fullFieldName, "array<" + arrayType + ">", null));
processedFields.add(fullFieldName);
LOG.debug("Added field '{}', Type: 'array<{}>'", fullFieldName, arrayType);

Expand All @@ -306,7 +310,7 @@ private void addCustomProperties(
Type typeEntity,
String schemaUri,
SchemaClient schemaClient,
Map<String, String> fieldTypesMap,
Map<String, FieldDefinition> fieldTypesMap,
Deque<Schema> processingStack,
Set<String> processedFields) {
if (typeEntity == null || typeEntity.getCustomProperties() == null) {
Expand All @@ -320,9 +324,13 @@ private void addCustomProperties(

LOG.debug("Processing custom property '{}'", fullFieldName);

Object customPropertyConfigObj = customProperty.getCustomPropertyConfig();

if (isEntityReferenceList(propertyType)) {
String referenceType = "array<entityReference>";
fieldTypesMap.putIfAbsent(fullFieldName, referenceType);
FieldDefinition referenceFieldDefinition =
new FieldDefinition(fullFieldName, referenceType, customPropertyConfigObj);
fieldTypesMap.putIfAbsent(fullFieldName, referenceFieldDefinition);
processedFields.add(fullFieldName);
LOG.debug("Added custom property '{}', Type: '{}'", fullFieldName, referenceType);

Expand All @@ -337,7 +345,9 @@ private void addCustomProperties(
}
} else if (isEntityReference(propertyType)) {
String referenceType = "entityReference";
fieldTypesMap.putIfAbsent(fullFieldName, referenceType);
FieldDefinition referenceFieldDefinition =
new FieldDefinition(fullFieldName, referenceType, customPropertyConfigObj);
fieldTypesMap.putIfAbsent(fullFieldName, referenceFieldDefinition);
processedFields.add(fullFieldName);
LOG.debug("Added custom property '{}', Type: '{}'", fullFieldName, referenceType);

Expand All @@ -351,17 +361,22 @@ private void addCustomProperties(
fullFieldName);
}
} else {
fieldTypesMap.putIfAbsent(fullFieldName, propertyType);
FieldDefinition entityFieldDefinition =
new FieldDefinition(fullFieldName, propertyType, customPropertyConfigObj);
fieldTypesMap.putIfAbsent(fullFieldName, entityFieldDefinition);
processedFields.add(fullFieldName);
LOG.debug("Added custom property '{}', Type: '{}'", fullFieldName, propertyType);
}
}
}

private List<FieldDefinition> convertMapToFieldList(Map<String, String> fieldTypesMap) {
private List<FieldDefinition> convertMapToFieldList(Map<String, FieldDefinition> fieldTypesMap) {
List<FieldDefinition> fieldsList = new ArrayList<>();
for (Map.Entry<String, String> entry : fieldTypesMap.entrySet()) {
fieldsList.add(new FieldDefinition(entry.getKey(), entry.getValue()));
for (Map.Entry<String, FieldDefinition> entry : fieldTypesMap.entrySet()) {
FieldDefinition fieldDef = entry.getValue();
fieldsList.add(
new FieldDefinition(
fieldDef.getName(), fieldDef.getType(), fieldDef.getCustomPropertyConfig()));
}
return fieldsList;
}
Expand Down Expand Up @@ -622,10 +637,12 @@ private String mapUrlToResourcePath(String url) {
public static class FieldDefinition {
private String name;
private String type;
private Object customPropertyConfig;

public FieldDefinition(String name, String type) {
public FieldDefinition(String name, String type, Object customPropertyConfig) {
this.name = name;
this.type = type;
this.customPropertyConfig = customPropertyConfig;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@ import {
ValueField,
} from 'react-awesome-query-builder';
import { useHistory, useParams } from 'react-router-dom';
import {
emptyJsonTree,
TEXT_FIELD_OPERATORS,
} from '../../../constants/AdvancedSearch.constants';
import { emptyJsonTree } from '../../../constants/AdvancedSearch.constants';
import { SearchIndex } from '../../../enums/search.enum';
import useCustomLocation from '../../../hooks/useCustomLocation/useCustomLocation';
import { TabsInfoData } from '../../../pages/ExplorePage/ExplorePage.interface';
import { getAllCustomProperties } from '../../../rest/metadataTypeAPI';
import advancedSearchClassBase from '../../../utils/AdvancedSearchClassBase';
import {
getTierOptions,
getTreeConfig,
Expand Down Expand Up @@ -225,15 +223,21 @@ export const AdvanceSearchProvider = ({

Object.entries(res).forEach(([_, fields]) => {
if (Array.isArray(fields) && fields.length > 0) {
fields.forEach((field: { name: string; type: string }) => {
if (field.name && field.type) {
subfields[field.name] = {
type: 'text',
valueSources: ['value'],
operators: TEXT_FIELD_OPERATORS,
fields.forEach(
(field: {
name: string;
type: string;
customPropertyConfig: {
config: string | string[];
};
}) => {
if (field.name && field.type) {
const { subfieldsKey, dataObject } =
advancedSearchClassBase.getCustomPropertiesSubFields(field);
subfields[subfieldsKey] = dataObject;
}
}
});
);
}
});
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ export const TEXT_FIELD_OPERATORS = [
'is_null',
'is_not_null',
];

export const DATE_FIELD_OPERATORS = ['between', 'not_between'];

/**
* Generates a query builder tree with a group containing an empty rule
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import {
SelectFieldSettings,
} from 'react-awesome-query-builder';
import AntdConfig from 'react-awesome-query-builder/lib/config/antd';
import {
DATE_FIELD_OPERATORS,
TEXT_FIELD_OPERATORS,
} from '../constants/AdvancedSearch.constants';
import { EntityFields, SuggestionField } from '../enums/AdvancedSearch.enum';
import { SearchIndex } from '../enums/search.enum';
import { getAggregateFieldOptions } from '../rest/miscAPI';
Expand Down Expand Up @@ -794,6 +798,94 @@ class AdvancedSearchClassBase {
},
};
};

public getCustomPropertiesSubFields(field: {
name: string;
type: string;
customPropertyConfig: {
config: string | string[];
};
}) {
{
switch (field.type) {
case 'array<entityReference>':
case 'entityReference':
return {
subfieldsKey: field.name + `.name`,
dataObject: {
type: 'select',
label: field.name,
fieldSettings: {
asyncFetch: advancedSearchClassBase.autocomplete({
searchIndex: (
(field.customPropertyConfig.config ?? []) as string[]
).join(',') as SearchIndex,
entityField: EntityFields.NAME_KEYWORD,
}),
useAsyncSearch: true,
},
},
};
case 'date-cp':
case 'dateTime-cp': {
return {
subfieldsKey: field.name,
dataObject: {
type: 'date',
operators: DATE_FIELD_OPERATORS,
},
};
}
case 'time-cp': {
return {
subfieldsKey: field.name,
dataObject: {
type: 'time',
operators: DATE_FIELD_OPERATORS,
},
};
}
case 'timeInterval': {
return {
subfieldsKey: [field.name + `.start`, field.name + `.end`],
dataObject: {
type: 'text',
label: field.name,
},
};
}

case 'table-cp': {
return {
subfieldsKey: field.name + '.first',
dataObject: {
type: 'text',
label: field.name,
valueSources: ['value'],
operators: TEXT_FIELD_OPERATORS,
},
};
}
// case "timestamp":
// case "string":
// case "markdown":
// case "number":
// case "integer":
// case "email":
// case "enum":
// case "duration":
default:
return {
subfieldsKey: field.name,
dataObject: {
type: 'text',
valueSources: ['value'],
operators: TEXT_FIELD_OPERATORS,
},
};
}
}
}
}

const advancedSearchClassBase = new AdvancedSearchClassBase();
Expand Down
Loading