您的位置:

esjava插件scriptengine,es 插件

本文目录一览:

如何与es交互

如何与es交互取决于你是否使用Java,这里默认我们都是使用Java语言的。es为Java用户提供了两种内置的客户端。

需要说明的是,两个Java客户端都通过9300端口与集群进行交互,使用es自己的传输协议。集群中的节点之间也通过9300端口进行通信。如果此端口未开放,你的节点将不能组成集群。

Java客户端所在的es版本必须与集群中其他的节点一致,否则,它们可能相互无法识别。

如果不是基于客户端的交互,该怎么办呢?es还为我们提供了基于http协议——以json为数据交互格式的restful API。通过9200端口与es进行通信,你甚至可以通过curl命令与es通信。

总结一下就是大概有三种交互方式。两种是客户端(9300),一种是restful接口(9200)。

es向量搜索插件-knn

1. knn向量检索插件

使用过下面两个插件

优点: 相对elastiknn,该插件支持把底层生成hnsw一个结构加载进内存,376w数据,768纬度向量,搜索性能在300-400ms左右

缺点: 

1.该插件需要基于nmslib生成一个c的so文件,该文件比较依赖底层操作系统的库,建立项目最好使用docker容器的方式,不然把本地打的so文件,放到其他环境会出现各种bug,比如: [libKNNIndexV1_7_3_6.so_0x6b1da]  _GLOBAL_sub_I_distcomp_sparse_scalar_fast.cc+0x2a

2. 该插件对应于es7.7.1的版本存在各种bug,比如打重复分数、使用cosine距离,但是实际算出来是l2距离,因此建议使用最新的版本,目前最新该插件对应的es版本是7.10.2

2.

优点: 这个是完全对接了es和luence语法的,应该java原生应用,这个不需要安装so库,官网直接就有插件,使用起来比较简单

缺点: 性能相对于上面插件有差距,看官网的QPS在400多左右

elasticsearch映射的数据类型有哪些

es支持大多数java里面的数据类型:

(一)核心数据类型:

(1)string: 默认会被分词,一个完整示例如下

"status": {

"type": "string", //字符串类型

"index": "analyzed"//分词,不分词是:not_analyzed ,设置成no,字段将不会被索引

"analyzer":"ik"//指定分词器

"boost":1.23//字段级别的分数加权

"doc_values":false//对not_analyzed字段,默认都是开启,分词字段不能使用,对排序和聚合能提升较大性能,节约内存

"fielddata":{"format":"disabled"}//针对分词字段,参与排序或聚合时能提高性能,不分词字段统一建议使用doc_value

"fields":{"raw":{"type":"string","index":"not_analyzed"}} //可以对一个字段提供多种索引模式,同一个字段的值,一个分词,一个不分词

"ignore_above":100 //超过100个字符的文本,将会被忽略,不被索引

"include_in_all":ture//设置是否此字段包含在_all字段中,默认是true,除非index设置成no选项

"index_options":"docs"//4个可选参数docs(索引文档号) ,freqs(文档号+词频),positions(文档号+词频+位置,通常用来距离查询),offsets(文档号+词频+位置+偏移量,通常被使用在高亮字段)分词字段默认是position,其他的默认是docs

"norms":{"enable":true,"loading":"lazy"}//分词字段默认配置,不分词字段:默认{"enable":false},存储长度因子和索引时boost,建议对需要参与评分字段使用 ,会额外增加内存消耗量

"null_value":"NULL"//设置一些缺失字段的初始化值,只有string可以使用,分词字段的null值也会被分词

"position_increament_gap":0//影响距离查询或近似查询,可以设置在多值字段的数据上火分词字段上,查询时可指定slop间隔,默认值是100

"store":false//是否单独设置此字段的是否存储而从_source字段中分离,默认是false,只能搜索,不能获取值

"search_analyzer":"ik"//设置搜索时的分词器,默认跟ananlyzer是一致的,比如index时用standard+ngram,搜索时用standard用来完成自动提示功能

"similarity":"BM25"//默认是TF/IDF算法,指定一个字段评分策略,仅仅对字符串型和分词类型有效

"term_vector":"no"//默认不存储向量信息,支持参数yes(term存储),with_positions(term+位置),with_offsets(term+偏移量),with_positions_offsets(term+位置+偏移量) 对快速高亮fast vector highlighter能提升性能,但开启又会加大索引体积,不适合大数据量用

}

(2)数字类型主要如下几种:

long:64位存储

integer:32位存储

short:16位存储

byte:8位存储

double:64位双精度存储

float:32位单精度存储

支持参数:

coerce:true/false 如果数据不是干净的,将自动会将字符串转成合适的数字类型,字符串会被强转成数字,浮点型会被转成整形,经纬度会被转换为标准类型

boost:索引时加权因子

doc_value:是否开启doc_value

ignore_malformed:false(错误的数字类型会报异常)true(将会忽略)

include_in_all:是否包含在_all字段中

index:not_analyzed默认不分词

null_value:默认替代的数字值

precision_step:16 额外存储对应的term,用来加快数值类型在执行范围查询时的性能,索引体积相对变大

store:是否存储具体的值

(3)复合类型

数组类型:没有明显的字段类型设置,任何一个字段的值,都可以被添加0个到多个,要求,他们的类型必须一致:

对象类型:存储类似json具有层级的数据

嵌套类型:支持数组类型的对象Aarray[Object],可层层嵌套

(4)地理类型

geo-point类型: 支持经纬度存储和距离范围检索

geo-shape类型:支持任意图形范围的检索,例如矩形和平面多边形

(5)专用类型

ipv4类型:用来存储IP地址,es内部会转换成long存储

completion类型:使用fst有限状态机来提供suggest前缀查询功能

token_count类型:提供token级别的计数功能

mapper-murmur3类型:安装sudo bin/plugin install mapper-size插件,可支持_size统计_source数据的大小

附件类型:需要 开源es插件支持,可存储office,html等类型

(6)多值字段:

一个字段的值,可以通过多种分词器存储,使用fields参数,支持大多数es数据类型

如何开发elasticsearch插件

检索引擎Elasticsearch支持插件模式,有些时候你可能需要安装一些插件,甚至自己开发插件,这里就提供一个开始ES插件开发示例,ES版本为1.5.2。

一、插件类继承自org.elasticsearch.plugins.AbstractPlugin

package org.elasticsearch.plugin.helloworld;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Collections;

import org.elasticsearch.common.component.LifecycleComponent;

import org.elasticsearch.common.inject.Module;

import org.elasticsearch.common.logging.ESLogger;

import org.elasticsearch.common.logging.Loggers;

import org.elasticsearch.common.settings.Settings;

import org.elasticsearch.plugins.AbstractPlugin;

import org.elasticsearch.rest.RestModule;

public class HelloWorldPlugin extends AbstractPlugin {

final ESLogger logger = Loggers.getLogger(getClass());

@Override

public String name() {

//插件名称

return "HelloWorld";

}

@Override

public String description() {

//插件描述

return "Hello World Plugin";

}

//处理模块,因为系统中有很多种Module,所以需要对其类型进行判断

@Override

public void processModule(Module module) {

if(module instanceof RestModule) {

((RestModule)module).addRestAction(HelloWorldHandler.class);

}

if(module instanceof HelloModule) {

logger.info("############## process hello module #####################");

}

}

@Override

public CollectionModule modules(Settings settings) {

//创建自己的模块集合

//如果没有自定义模块,则可以返回空

HelloModule helloModule = new HelloModule();

ArrayListModule list = new ArrayList();

list.add(helloModule);

Collections.unmodifiableList(list);

return list;

}

@SuppressWarnings("rawtypes")

@Override

public CollectionClass? extends LifecycleComponent services() {

//创建自己的服务类集合,服务类需要继承自LifecycleComponent,ES会自动创建出服务类实例,并调用其start方法

//如果没有自定义服务类,则可以返回空

CollectionClass? extends LifecycleComponent list = new ArrayList();

list.add(HelloService.class);

return list;

}

}

Module类其实就是定义了依赖注入规则,如果不清楚,可以去查看Google Guice的文档,基本上是一致的。如上例中的HelloModule:

package org.elasticsearch.plugin.helloworld;

import org.elasticsearch.common.inject.AbstractModule;

import org.elasticsearch.common.inject.Scopes;

public class HelloModule extends AbstractModule {

@Override

protected void configure() {

//将InjectableService接口类型绑定到InjectableServiceImpl实现类

//在需要注入InjectableService的地方,就会使用InjectableServiceImpl实例

bind(InjectableService.class).to(InjectableServiceImpl.class);

//使HelloService为单例状态

bind(HelloService.class).in(Scopes.SINGLETON);

}

}

不同的模块有不同的处理方式,例如例子中对于RestModule,添加了一个Handler:

package org.elasticsearch.plugin.helloworld;

import org.elasticsearch.client.Client;

import org.elasticsearch.common.inject.Inject;

import org.elasticsearch.common.settings.Settings;

import org.elasticsearch.rest.BaseRestHandler;

import org.elasticsearch.rest.BytesRestResponse;

import org.elasticsearch.rest.RestChannel;

import org.elasticsearch.rest.RestController;

import org.elasticsearch.rest.RestRequest;

import org.elasticsearch.rest.RestStatus;

import org.elasticsearch.rest.RestRequest.Method;

import org.elasticsearch.rest.RestResponse;

public class HelloWorldHandler extends BaseRestHandler {

//注入对象

@Inject

protected HelloWorldHandler(Settings settings, RestController controller, Client client) {

super(settings, controller, client);

//将该Handler绑定到某访问路径

controller.registerHandler(Method.GET, "/hello/", this);

controller.registerHandler(Method.GET, "/hello/{name}", this);

}

//处理绑定路径的请求访问

@Override

protected void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {

logger.debug("HelloWorldAction.handleRequest called");

final String name = request.hasParam("name") ? request.param("name") : "world";

String content = "{\"success\":true, \"message\":\"hello " +name+ "\"}";

RestResponse response = new BytesRestResponse(RestStatus.OK, BytesRestResponse.TEXT_CONTENT_TYPE, content);

channel.sendResponse(response);

}

}

最后在类路径根目录下添加一个名为es-plugin.properties属性文件,指定插件实现类:

plugin=org.elasticsearch.plugin.helloworld.HelloWorldPlugin

二、将插件打成jar包后安装

假设ES_HOME代表Elasticsearch安装目录。在ES_HOME/plugins目录下创建一个名为HelloWorld的目录,该目录名称必须与插件名称相同(区分大小写),然后将jar包拷贝至HelloWorld目录,重新启动即可,当你执行:

curl -GET localhost:9200/hello,就会返回相应结果了。

三、为插件添加页面

如果你想为你的插件添加访问页面,则可以在ES_HOME/plugins/HelloWorld目录下创建一个名为"_site"的目录,该目录名称必须为_site,然后将相应的html页面放置进_site目录即可,如果放置了一个名为index.html文件,则可以通过

localhost:9200/_plugin/HelloWorld/index.html进行访问。

由于Elasticsearch提供了js客户端API,所以使用html静态页面与js就可以完成相应的功能了。