全文索引
SequoiaDB 全文检索能够实现近实时的搜索能力,即一个新的文档从被索引到可被搜索会有一定的延迟。延迟取决于索引的速度。主要分两种情况:
- 在空集合或者只有很少量数据的集合上创建全文索引。在写入压力不是太大的情况下,通常在若干秒(典型值如 1~5 秒)内,新增的数据即可被搜索到。
- 创建索引时,集合中已存在大量的数据。此时要全量索引集合中的所有文档,耗时从分钟级到若干小时不等,取决于数据规模、搜索服务器性能等因素。如果在全量索引完成之前进行查询,只能查到部分结果。
SequoiaDB 使用 Elasticsearch 作为全文检索引擎实现全文索引。全文索引与普通索引的最大区别在于,索引数据不是存在于数据节点的索引文件中, 而是存储在 Elasticsearch 中。在使用该索引进行查询的时候,会在 Elasticsearch 中进行搜索,数据节点根据其返回的结果,再到本地查找数据。实现时涉及以下三个角色:
- SequoiaDB 数据节点:存储数据
- Elasticsearch 集群:用于存储全文索引数据,以及在索引中进行搜索
- 适配器 sdbseadapter:作为 SequoiaDB 数据节点与 Elasticsearch 交互的桥梁,进行数据转换与传输等
例如,有 SequoiaDB 3 组 1 节点的集群和 Elasticsearch 集群。某集合数据均匀切分到所有数据组上。在该集合上使用全文索引进行检索,流程如图。
协调节点先将请求分发给所有数据组,数据节点转发搜索请求给 Elasticsearch 集群,Elasticsearch 在索引中搜索到结果后,由数据节点将真实数据返回给协调节点。协调节点再进行汇总后,返回给客户端。
SequoiaDB 通过与 Elasticsearch 配合提供全文检索能力。使用全文检索时必须完成 Elasticsearch 集群的部署,并配置好 SequoiaDB 的搜索引擎适配器。具体参考。
sdbseadapter 是 SequoiaDB 与 Elasticsearch 连接的桥梁,以在 SequoiaDB 上支持全文检索能力的工具。
适配器与数据节点一一对应,每个适配器需要使用一个单独的配置文件(或手工指定启动参数)。在安装路径下的 conf/samples 目录中有配置文件模板 sdbseadapter.conf,可将该文件拷贝到目标路径下并按实际组网进行配置。建议在数据节点的 conf 目录下创建单独的目录(如 seadapter),并在该目录中按节点服务端口号创建子目录,分别存放各自的配置文件。
全文检索功能需要在 SequoiaDB 集群环境下使用,单机模式暂不支持。要使用全文检索功能,需要完成 Elasticsearch 集群、SequoiaDB 集群及搜索引擎适配器部署。
由于在 Elasticsearch 中创建的索引的名字,是由集合的 Unique ID、原始索引名等元素组合而成,不同的 SequoiaDB 集群间这些值可能相同,因此建议每个 SequoiaDB 集群使用独立的 Elasticsearch 集群,不要混用,否则可能造成数据错误。
软件安装
SequoiaDB 的搜索引擎适配器已包含在软件发布包中,按照 SequoiaDB 的安装步骤正常完成安装即可。适配器可执行程序为安装目录下的 bin/sdbseadapter。
2.Elasticsearch 安装
请到 下载 Elasticsearch 安装包,并按照实际业务需要,参考 Elasticsearch 相关文档完成软件安装及集群部署。当前 SequoiaDB 适配的 Elasticsearch 版本为 6.2.2。
- SequoiaDB 及 Elasticsearch 部署
用户可以参考 SequoiaDB 及 Elasticsearch 的相关指导,完成 SequoiaDB 及 Elasticsearch 集群的部署,并确保其正常运行。
- 搜索引擎适配器部署
1.适配器节点配置文件准备
每一个数据节点(包括主节点和备节点)需要启动一个对应的适配器节点,二者需要运行在同一台主机上。适配器启动的时候必需指定配置文件路径,且一个配置文件只能启动一个适配器实例。尝试使用同一个配置文件启动多个适配器实例将会失败。
当需要使用全文检索功能时,在 SequoiaDB 安装目录的 conf 目录下,创建 seadapter 目录,并在该目录下,按适配器对应的数据节点的服务端口号,分别创建下层子目录并存放一份配置文件。配置文件模板可从 conf/samples/sdbseadapter.conf 拷贝,文件名应保持一致,然后依次对配置文件内容进行修改。如下以 SequoiaDB 安装路径为 /opt/sequoiadb,数据节点服务端口号分别为 11830,11840,11850 为例进行说明:
分别修改上述配置文件,填写数据节点及 Elasticsearch 的地址信息。如 11830 下配置文件内容如下(IP 及服务端口号按实际填写):
datasvcname=11830
searchenginehost=192.168.1.124
searchengineport=9200
diaglevel=3
optimeout=30000
2.适配器节点启动
目前适配器进程通过手工方式启动,通过 -c 指定配置文件路径(不需要带配置文件名):
$ nohup sdbseadapter -c /opt/sequoiadb/conf/seadapter/11830 &
$ nohup sdbseadapter -c /opt/sequoiadb/conf/seadapter/11840 &
$ nohup sdbseadapter -c /opt/sequoiadb/conf/seadapter/11850 &
结果参考:
sdbseadapter(11837) A
sdbseadapter(11847) A
sdbseadapter(11857) A
括号内为其监听搜索请求的端口号。
创建全文索引
创建全文索引需使用接口。使用格式如下:
createIndex(<索引名>, { <字段1>: "text", [<字段2>: "text"...] });
全文索引可以指定一个或多个字段,普通索引的其它选项(如 Unique, NotNull…)均对全文索引无效,无需指定。例如,在 sample.employee 集合上为 name 及 address 字段上创建复合全文索引,使用语句如下:
SequoiaDB 通过在查询中指定 Elasticsearch 的搜索条件来进行全文检索。基本语法结构为:
find({ "": { "$Text": <search command> } })
其中即 Elasticsearch 的搜索条件,须使用 Elasticsearch 的 (Domain Specific Language)语法。详情参考 Elasticsearch DSL 官方文档。
示例中,在集合 sample.employee
中查找 name 中包含”Smith”的所有记录:
> var cl = db.createCS('sample').createCL('employee')
Takes 1.246399s.
> cl.createIndex('idx_1', {first_name:"text", "last_name":"text", "age":"text", "about":"text", "interests": "text"})
Takes 1.182447s.
> cl.insert({"first_name" : "John","last_name" : "Smith","age" : 25,"about" : "I love to go rock climbing","interests": [ "sports", "music" ]})
Takes 0.009290s.
> cl.insert({"first_name" : "Jane","last_name" : "Smith","age" : 32,"about" : "I like to collect rock albums","interests": [ "music" ]})
Takes 0.001013s.
> cl.insert({"first_name" : "Douglas","last_name" : "Fir","age" : 35,"about": "I like to build cabinets","interests": [ "forestry" ]})
Takes 0.001004s.
> cl.find({"":{"$Text":{"query":{"match":{"about" : "rock climbing"}}}}}).hint({"":"idx_1"})
{
"$oid": "5a8f8d9c89000a0906000000"
},
"first_name": "John",
"last_name": "Smith",
"about": "I love to go rock climbing",
"interests": [
"sports",
"music"
]
}
{
"_id": {
"$oid": "5a8f8d9f89000a0906000001"
},
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [
"music"
]
}
删除全文索引
使用SdbCollection.dropIndex(<name>)接口指定索引名即可删除全文索引。
示例: