下面是我的一个文档的样子
{
"CC":{"colors":["Blue","Green","Yellow"]},
"CN":{"colors":["White","Green","Blue"]},
"WA":{"colors":["Orange","Green","Blue"]},
...
}
我想要一个术语聚合,在两个字段CC. color
和CN.color
的交叉点上。也就是说,对于这个文档,该字段将在交叉点上有["Green","Blue"]
,我想要一个关于这个交叉点的术语聚合。
据我了解,有两种方法可以做到这一点。
2)在索引时间创建一个新字段,可能称为CC_CN. color
,它保存所有文档的交集。
我不能继续2,因为我的组合太多了。我可以在搜索期间有任何需求,如CC_CN、CC_WA或WA_CN_CC等。
对于1)来说,它是有效的,但是非常慢。一个原因是1)不能使用全局序数。
有什么技巧可以让我让 elastic 为我的无痛项聚合构建一个自定义全局序数吗?我知道我的系统中只有 25 种颜色,所以可以在某处将所有颜色赋予弹性,并“保证”他们不会从聚合中返回除这些颜色之外的任何其他颜色?
或者,如果我在索引中编码和存储数字而不是字符串,这对弹性来说会更快吗?例如,0代替“黑色”,1代替“绿色”等。?
除了交集,我的其他用例涉及联合等。也是。感谢阅读!
为了自己回答,我们最终在< code>_source中要求这些数组,并在Ruby中执行union/intersection。
也可以无痛地做到这一点,这提供了更好的性能。Elastic使用map
进行聚合,我想不出任何使用全局序数的方法。我认为这是不可能的。
我们编写了生成无痛代码的代码,以执行数组之间的交集和并集。对于任何未来的漫游者,下面是生成的代码的样子:
这是针对工会的:
Stream stream = [].stream();
String[] stream_keys = new String[] {'CC.colors', 'CN.colors'};
for (int i = 0; i < stream_keys.length; ++i) {
if (doc.containsKey(stream_keys[i])) {
stream = Stream.concat(stream, doc[stream_keys[i]].stream());
}
}
stream = stream.distinct();
这是交叉点(流,list_0_stream和list_1_stream交叉点):
List list_0 = list_0_stream.collect(Collectors.toList());
List list_1 = list_1_stream.collect(Collectors.toList());
return stream.filter(list_0::contains).filter(list_1::contains).toArray();
表现似乎可以接受。
有2种方法提供给您
花费了我很多时间
^ ^
ColorMap={"Blue":0,"Green":1,"Yellow":2,"White":3,"Orange":4};
ReverseColorMap=["Blue","Green","Yellow","White","Orange"];
var All={
"CC":{"colors":["Blue","Green","Yellow"]},
"CN":{"colors":["White","Green","Blue"]},
"WA":{"colors":["Orange","Green","Blue"]}
};
//Cover Encode
function EncodeColor(T1){
var T2 = JSON.parse(JSON.stringify(T1));//Clone Original
for(var i in T2){
for(var j in T2[i]["colors"]){
T2[i]["colors"][j]=ColorMap[T2[i]["colors"][j]];
}
}
return T2;
}
var NewAll=EncodeColor(All);
console.log(All);
console.log(NewAll);
function SortColor(T1){
for(var i in T1){
T1[i]["colors"].sort((a, b) => {
return a-b;
});
}
}
function BuildSameColor(T1){
var CombineNew={};
var Name_Temp=[];
for(var i in T1){
Name_Temp.push(i);
}
for(var i =0;i<Name_Temp.length;i++){
for(var j =i+1;j<Name_Temp.length;j++){//j=i+1 because CC_CC not valid CC_CN is valid etc...
CombineNew[Name_Temp[i]+"_"+Name_Temp[j]]={"colors":T1[Name_Temp[i]]["colors"].concat(T1[Name_Temp[j]]["colors"])};//combine color array
}
}
SortColor(CombineNew);//Sort Result
//Sort will reduce compare time(later) when color is a lot
for(var i in CombineNew){
var NewAr=[];
for(var j=0;j<CombineNew[i]["colors"].length-1;j++){
if(CombineNew[i]["colors"][j]==CombineNew[i]["colors"][j+1]){
NewAr.push(CombineNew[i]["colors"][j]);
}
}
CombineNew[i]["colors"]=NewAr;
}
return CombineNew;
}
var TTT=BuildSameColor(NewAll);
console.log(TTT);
//Then Decode Color
function DecodeColor(T1){
var T2 = JSON.parse(JSON.stringify(T1));//Clone Original
for(var i in T2){
for(var j in T2[i]["colors"]){
T2[i]["colors"][j]=ReverseColorMap[T2[i]["colors"][j]];
}
}
return T2;
}
var TTTQQ=DecodeColor(TTT);
console.log(TTTQQ);
//This Also work any length of color
var Examp={
"CC":{"colors":["Blue","Green","Yellow","Orange"]},
"CN":{"colors":["White","Green","Blue"]},
"WA":{"colors":["Orange","Green","Blue"]}
};
var E_Examp=EncodeColor(Examp);
var Com_E_E_Examp=BuildSameColor(E_Examp);
var D_Examp=DecodeColor(Com_E_E_Examp);
console.log(D_Examp);