es 插件 求汉明距离

package org.com.plugin;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;

import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugins.ScriptPlugin;
import org.elasticsearch.script.ScriptEngine;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.SearchScript;
import org.apache.lucene.index.LeafReaderContext;
import org.elasticsearch.search.lookup.LeafDocLookup;
import org.elasticsearch.index.fielddata.ScriptDocValues;

public class Hamming extends Plugin implements ScriptPlugin{
    
    @Override
    public ScriptEngine getScriptEngine(Settings settings, Collection<ScriptContext<?>> contexts) {
        return new MyExpertScriptEngine();
    }
    private static class MyExpertScriptEngine implements ScriptEngine {
        @Override
        public String getType() {
            return "expert_scripts";
        }
        
        @Override
        public <T> T compile(String scriptName, String scriptSource, ScriptContext<T> context, Map<String, String> params) {
            if (context.equals(SearchScript.CONTEXT) == false) {
                throw new IllegalArgumentException(getType() + " scripts cannot be used for context [" + context.name + "]");
            }
            if ("Hamming".equals(scriptSource)) {
                SearchScript.Factory factory = (p, lookup) -> new SearchScript.LeafFactory() {  
                    private Set<Map.Entry> pms = ((Map)p.get("m")).entrySet();                                                                          
                    private double d_diff = Double.valueOf((String)p.get("diff"));
                    @Override
                    public SearchScript newInstance(LeafReaderContext context) throws IOException {
                        return new SearchScript(p, lookup, context) {                                                     
                            @Override
                            public double runAsDouble() {
                                double d_res = 0D;
                                LeafDocLookup ldl = getDoc();
                                if (null == ldl) {
                                    return -1D;
                                }                              
                                for(Map.Entry e : pms){
                                    String s = (String)e.getKey();
                                    long l_t;
                                    try {
                                        l_t = (long)e.getValue();
                                    } catch (ClassCastException ccex) {
                                        l_t = (int)e.getValue();
                                    }
                                    try {
                                        ScriptDocValues.Longs l_s = (ScriptDocValues.Longs)ldl.get(s);
                                        d_res += hammingDistance(l_t, l_s.getValue());
                                    } catch (Exception ex){
                                        return -1D;
                                    }                                   
                                    if (d_res > d_diff) {
                                        return -1D;
                                    }                                  
                                };
                                return d_res;
                            }
                        };
                    }

                    @Override
                    public boolean needs_score() {
                        return false;
                    }
                    
                    private double hammingDistance(long x, long y) {
                        double cnt = 0D;
                        long hamming = x ^ y;
                        while(hamming > 0) {
                            hamming = hamming & (hamming - 1);
                            cnt += 1;
                        }
                        return cnt;
                    }              
                };
                return context.factoryClazz.cast(factory);
            }
            throw new IllegalArgumentException("Unknown script name " + scriptSource);
        }
        @Override
        public void close() {
        }
    }
}

调用

{
  "_source": [
    "id"
  ],
  "query": {
    "function_score": {
      "functions": [
        {
          "script_score": {
            "script": {
              "source": "Hamming",
              "lang": "expert_scripts",
              "params": {
              		"m":{
              	  	"f_0": 19210667227652650,
                	"f_1": 2305843013508960000
                	},
                	"diff":"500"
              }
            }
          }
        }
      ]
    }
  }
}

参数和字段要对上 (数据中要有f_0 ,f_1)字段

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值