本文写于 9 年前(2016 年 10 月),部分内容可能已经过时。
知识图谱在线系统的schema除了定义每个实体的属性之外,还有一个信息需要策略同学告诉我们——就是哪些字段需要索引,以及索引的方式,这点非常类似于ElasticSearch的Mapping:
PUT /my_index
{
"mappings": {
"my_type": {
"properties": {
"status_code": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
mapping针对每个字段,有个index属性,可以指定索引的方式:
- no: Do not add this field value to the index. With this setting, the field will not be queryable.
- not_analyzed: Add the field value to the index unchanged, as a single term. This is the default for all fields that support this option except for string fields. not_analyzed fields are usually used with term-level queries for structured search.
- analyzed: This option applies only to string fields, for which it is the default. The string field value is first analyzed to convert the string into terms (e.g. a list of individual words), which are then indexed. At search time, the query string is passed through (usually) the same analyzer to generate terms in the same format as those in the index. It is this process that enables full text search.
ES使用了JSON作为schema,但是我们已经用了protobuf,能不能直接在protobuf的基础上直接增加这个信息呢?查看了一下protobuf的文档,Protobuf提供的Custom Options刚好可以解决这个问题。
我们可以自定义这么一个Field Option:
package graphsearch;
import "google/protobuf/descriptor.proto";
enum IndexType {
NO = 0;
NOT_ANALYZED = 1;
ANALYZED = 2;
}
extend google.protobuf.FieldOptions {
optional IndexType index = 51234 [default = NO];
}
说明:
- Options分为file-level,message-level,field-level等几种,这里我们使用field-level的options。
- 自定义选项可以被定义为proto中的任意类型,如string, int32, enum, 甚至message。这里使用了枚举,而且默认值设置为NO,跟ES不一样。
然后就可以这么使用了:
package graphsearch;
import "schema_index.proto";
message Person {
required string name = 1 [(index) = NO];
required uint32 age = 2;
}
注意:使用这个选项的时候,选项名称必须被放置在()里,以表明这是一个扩展。
然后,我们可以这样读取这个option的值:
Descriptors.Descriptor desc = Person::descriptor();
List<Descriptors.FieldDescriptor> field_desc_list = desc.getFields();
foreach(Descriptors.FieldDescriptor field_desc : field_desc_list){
Descriptors.Descriptor options = field_desc.getOptions();
Enum value = options.GetExtension(index);
// ...
}
参考文档
- Elasticsearch Reference [2.4] » Mapping » Mapping parameters » index
- Options
- Python Protocol Buffer field options
- Descriptors.Descriptor
- Descriptors.FieldDescriptor
- DescriptorProtos.FieldOptions
本文由 arganzheng 创作,采用 CC BY 4.0 许可协议。在保留原文作者、署名以及完整原文链接(https://arganzheng.life/make-good-use-of-protobuf-custom-options.html)的前提下,欢迎各种形式的转载、翻译或商业引用。
COMMENTS
评论存放在 GitHub Discussions, 用 GitHub 账号登录即可发表,支持 Markdown。 想针对正文某句话说?选中那段文字,点浮出的「评论」即可划线评论;觉得哪里写错了,发表时勾上「同时提交 Issue」。 有人回复你时 GitHub 会按你的通知设置发邮件,不用守在这里。