v2.0.1
全文索引
内容包含比较长的句子,因为全文索引限制256个字节,导致存在中文字符被截断的风险。
截断后在es那边无法识别为utf8【Invalid UTF-8 middle byte 0x22\n at [Source: org.elasticsearch.common.bytes.BytesReference$MarkSupportingStreamInputWrapper@357e8a0】,导致创建索引失败。
然后会导致【A fatal error . Full-text engine is not working.】之类的错误。
之后会死循环创建索引环节。
看代码确实是直接截断的。
好问题,
UTF8下普通的中文字符占3个字节, 256/3 还多着一个字符,导致一个无效的字符(一个中文字符的一个字节)。
后面nebula字符集功能会统一处理的。
嗯嗯 我这边快要上线了,看了一下【MAX_INDEX_TYPE_LENGTH】相关的好像就是storage里面用到了,我尝试着自己编译一个不受限制的版本试试看,本身内容也不会特别长,但有一些内容肯定超过了256字节。
# 拉取nebula开发环境
git clone https://github.com/vesoft-inc/nebula-dev-docker.git
# 拉取nebula开发环境docker
sudo docker pull vesoft/nebula-dev:centos7
# 启动docker进入docker环境
sudo ./run.sh
# 新建目录
mkdir -p /data/code/
cd /data/code/
# 拉取storage代码
git clone -b v2.0.1 https://github.com/vesoft-inc/nebula-storage.git
# 创建构建目录
cd nebula-storage
mkdir build
# 下载common源码
cmake -DENABLE_BUILD_STORAGE=on -DENABLE_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DNEBULA_COMMON_REPO_TAG=v2.0.1 ..
# 修改索引限制和docID 长度限制
vim ../modules/common/src/common/plugin/fulltext/FTUtils.h
# 清空build目录重新生成cmake文件
rm -rf *
cmake -DENABLE_BUILD_STORAGE=on -DENABLE_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DNEBULA_COMMON_REPO_TAG=v2.0.1 ..
# 编译
nohup make &
# 将镜像中二进制文件拷贝出来
sudo docker cp containerid:/data/nebula-storage/build/bin/nebula-storaged /data/nebula/code/nebula-dev-docker/nebula/
目前我的解决方案就是简单定义一下自己的值。当然大家可以根据业务来,或者这里的256字节动态计算,只要不对多字节字符进行截断就无大碍。
修改文件:/data/nebula-storage/modules/common/src/common/plugin/fulltext/FTUtils.h
// 自定义了两个长度
// 放开256限制
#define MAX_VALUE_LEN 2147483647
// es文档ID长度是512字节,所以这里还是流出256个字节吧
#define MAX_ID_LEN 256
...
static std::string val(const std::string &v) {
return ((v.size() > MAX_VALUE_LEN) ? v.substr(0, MAX_VALUE_LEN) : v);
}
static std::string docId(const DocItem& item) {
// partId_schemaId_column_value,
// The value length limit is 255 bytes
// docId structure : partId(10bytes) + schemaId(10Bytes) +
// columnName(32bytes) + encoded_val(max 344bytes)
// the max length of docId is 512 bytes, still have about 100 bytes reserved
// 这里替换一下MAX_VALUE_LEN即可。
auto encoded = encryption::Base64::encode((item.val.size() > MAX_ID_LEN)
? item.val.substr(0, MAX_ID_LEN)
: item.val);
std::replace(encoded.begin(), encoded.end(), '/', '_');
std::stringstream ss;
ss << id(item.part) << id(item.schema) << column(item.column) << encoded;
return ss.str();
}
system
关闭
13
此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。