我正在开发一个搜索API,它支持使用Elasticsearch和GraphQL-Java的聚合。
Elasticsearch:-ES支持一个名为include和exclude的功能,顾名思义,它将只包括或排除用户在输入中要求的聚合字段。
包含和排除输入可以通过两种方式给出:
-
作为RegEx。
例如:";包括":"P.*";
-
作为精确值的数组
例如:";包括":["浦那","孟买"]
因此,为了支持这两种输入,我维护了一个类型为
input : [String]
问题:我想同时支持RegEx(String(和精确值数组[String],但对于上面的类型即[String]来说,即使我在include中传递了一个Single String作为输入,它仍然会被认为是一个值为的字符串数组
包括:";P."--->包括:["P."],
所以我不能在Java中进行instanceOf检查,因为它总是数组
据我所知,GraphQL不支持输入类型的并集,所以我不能将include的输入类型更改为
include : String | [String]
有人能告诉我一个解决方案吗?
由于问题是由于include和exclude的输入类型造成的,我在GraphQL名称中定义了一个自定义标量类型"StringOrArrayOfString";
在GraphQLJava中,这可以按如下方式完成:
GraphQLScalarType.newScalar().name("StringOrArrayOfString")
.description("Custom scalar for include and exclude in Aggregation")
.coercing(new Coercing() {
@Override
public Object serialize(Object dataFetcherResult) {
return serializeStringOrArrayOfString(dataFetcherResult);
}
@Override
public Object parseValue(Object input) {
return parseStringOrArrayOfString(input);
}
@Override
public Object parseLiteral(Object input) { return parseStringOrArrayOfStringLiteral(input); }
}).build();
private static Object serializeStringOrArrayOfString(Object result) {
if(result instanceof String) {
return result.toString();
}
if(result instanceof List) {
return result;
} else {
throw new CoercingSerializeException(String.format("Unable to serialize %s.",result));
}
}
并为include和exclude定义了该类型。
包括:StringOrArrayOfString
一旦我得到include/exclude值,我就会检查instanceOf并调用相应的Elasticsearch生成器。