elastic,我可以使用我自己的全局序号和一个无痛的术语聚合脚本吗?

elastic, can I use my own global ordinals with a painless terms aggregation script?

这是我的一份文档的样子


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

我想要在两个字段 CC.colorsCN.colors 的交集上进行术语聚合。也就是说,对于本文档,该字段将在交集上有 ["Green", "Blue"],而我想要在该交集上进行术语聚合。

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

1) 聚合方面的无痛脚本,return 是每个文档的这两个数组的交集。 2) 在索引期间创建的新字段,可能称为CC_CN.colors,它包含所有文档的交集。

我无法继续使用 2,因为我的组合太多了。我可以在搜索期间有任何需要,例如CC_CN,或CC_WA,或WA_CN_CC等

对于 1),它可以工作,但变得非常慢。一个原因是 1) 不能使用全局序数。

有什么技巧可以让 elastic 为我的无痛术语聚合构建自定义全局序数吗?我知道我的系统中只有 25 种颜色,所以可以将所有颜色赋予弹性某处,并且 "assure" 它们我不会 return 除了这些来自我的聚合的颜色之外的任何其他颜色?

或者,如果我在索引中编码和存储数字而不是字符串,这对于 elastic 来说会更快吗?例如0 而不是 "Black",1 而不是 "Green" 等等?

除了交集,我的其他用例还涉及并集等。感谢阅读!

有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);

请加入!!!!!!!!!

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 StaticSearch(T1,Name1,Name2){
  if(Name1 in T1 && Name2 in T1 ){
  
    var Temp= T1[Name1]["colors"].concat(T1[Name2]["colors"]);
    var T2=[];
    Temp.sort((a, b) => {
      return a-b;
    });
    for(var i=0;i<Temp.length-1;i++){
      if(Temp[i]==Temp[i+1]){
        T2.push(Temp[i]);
      }
    }
    var ReturnObj={};
    ReturnObj[Name1+"_"+ Name2]={};
    ReturnObj[Name1+"_"+ Name2]["colors"]=T2;
    return ReturnObj;
  }
  return null;
  
}
var SearchResult=StaticSearch(NewAll,"CC","CN");

console.log(SearchResult);
//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(SearchResult);

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=StaticSearch(E_Examp,"WA","CC");
var D_Examp=DecodeColor(Com_E_E_Examp);
console.log(D_Examp);

另一种方法静态搜索

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

表现尚可。