提问者:小点点

弹性,我可以使用我自己的全局序数和无痛的术语聚合脚本吗?


下面是我的一个文档的样子


    {
      "CC":{"colors":["Blue","Green","Yellow"]},
      "CN":{"colors":["White","Green","Blue"]},
      "WA":{"colors":["Orange","Green","Blue"]},
       ...
    }

我想要一个术语聚合,在两个字段CC. colorCN.color的交叉点上。也就是说,对于这个文档,该字段将在交叉点上有["Green","Blue"],我想要一个关于这个交叉点的术语聚合。

据我了解,有两种方法可以做到这一点。

2)在索引时间创建一个新字段,可能称为CC_CN. color,它保存所有文档的交集。

我不能继续2,因为我的组合太多了。我可以在搜索期间有任何需求,如CC_CN、CC_WA或WA_CN_CC等。

对于1)来说,它是有效的,但是非常慢。一个原因是1)不能使用全局序数。

有什么技巧可以让我让 elastic 为我的无痛项聚合构建一个自定义全局序数吗?我知道我的系统中只有 25 种颜色,所以可以在某处将所有颜色赋予弹性,并“保证”他们不会从聚合中返回除这些颜色之外的任何其他颜色?

或者,如果我在索引中编码和存储数字而不是字符串,这对弹性来说会更快吗?例如,0代替“黑色”,1代替“绿色”等。?

除了交集,我的其他用例涉及联合等。也是。感谢阅读!


共2个答案

匿名用户

为了自己回答,我们最终在< 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);