一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して13日目です
序文
canalを使用して最後のelasticsearchを継承し、配列フィールドを処理します。実際、最初の不注意により、運河構成ファイルでobjFieldフィールドの配列構成が有効になっておらず、配列として最初にマップされると予想していたフィールドが文字列フィールドに正常にマップされました。したがって、疑問が生じます。たとえば、elasticsearchに商品オブジェクトがあり、複数のラベルに対応できます。商品のドキュメントに関連付けられたラベルID、中国語のラベル、英語のラベルを保存する必要があります。何らかの理由で、配列として格納されるはずだったこれらのフィールドは、句読点(セミコロンなど)で連結された文字列に圧縮されました。
{
"labels": "1;2;3",
"labels_cn": "历史;中国;精品课",
"labels_en": "history;china;class quality"
}
{
"label_cn_names": {
"type": "text"
},
"label_en_names": {
"type": "text"
},
"labels": {
"type": "text"
}
}
复制代码
上記はドキュメントストレージの一部です。1。ストレージは文字列です。2。フィールドタイプはテキストです。
検索時にテキストがセグメント化されます。たとえば、タグID、中国語タグ、英語タグで検索する必要があります。
31="31番目のラベルIDにバインドされたオブジェクトを取得します
China="バインドされた中国語タグは中国のオブジェクトです
中国=>バインドされた英語タグを取得することは中国の目的です。
たとえば、一致するクエリがあいまいな場合、タグが誤ってヒットする傾向がある場合、英語でbagを検索すると、タグ「shcoolandbag」も返されます。中国語ではI国を検索すると、タグ「中国」も返されます。テキストタイプは検索中に分析およびセグメント化され、デフォルトの標準トークナイザーまたはikトークナイザーは単語セグメント化後に誤動作するためです。この分割文字列では、「配列」内の個々の値を正確に一致させる必要もあります。では、単語のセグメンテーションから始める必要がありますか?たとえば、区切り文字によれば、各単語のセグメンテーションは配列の各値であるため、検索中にアナライザーによって単語のセグメンテーションが実行された場合でも、各セグメンテーションの単語の値は完全になります。一致しました。
カスタム分詞
まず、elasticsearchのアナライザーが3つの部分で構成されていることを簡単に説明しましょう:1、0以上の文字フィルター2、トークナイザー3、0以上のトークンフィルター私たちがしなければならないのは、トークナイザーを作成することだけです。パターントークナイザーの場合。パターンセグメンテーションとは、正規表現によるテキストの分離を指します。
PUT my-index-000001
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "pattern",
"pattern": ","
}
}
}
}
}
POST my-index-000001/_analyze
{
"analyzer": "my_analyzer",
"text": "comma,separated,values"
}
复制代码
例如这是一个逗号的分词器。所有文本会按照逗号分隔。我们给我们的索引创建一个分号的分词器。 下面来看下比较,首先是没有用自定义分词器的
{
"query":{
"match":{
"labels_cn": "课"
}
}
}
--------------------
"hits": [
{
"_index": "book",
"_type": "_doc",
"_id": "HjPUJ4ABRHGvpe9lz-Be",
"_score": 0.2876821,
"_source": {
"book_name": "畅销书",
"labels": "1;2;3",
"labels_cn": "历史;中国;精品课",
"labels_en": "history;china;class quality"
}
}
]
复制代码
可以看到有结果返回,可以理论上只有搜索精品课才能返回。这是由于labels_cn被分词了,例如你是用了ik,那么很有可能分词为精品、课。所以就会被误匹配。 下面我们增加自定义分词器,然后再进行同样的查询
{
"query":{
"match":{
"labels_cn": "课"
}
}
}
------------
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
复制代码
很神奇,没有返回。为了方便理解,我们测试下分词器的作用,使用_analyze API
{
"analyzer": "semicolon_analyzer",
"text": "历史;中国;精品课"
}
{
"tokens": [
{
"token": "历史",
"start_offset": 0,
"end_offset": 2,
"type": "word",
"position": 0
},
{
"token": "中国",
"start_offset": 3,
"end_offset": 5,
"type": "word",
"position": 1
},
{
"token": "精品课",
"start_offset": 6,
"end_offset": 9,
"type": "word",
"position": 2
}
]
}
复制代码
看到文本只会按照分号进行分词。所以也只可能被完整的标签值匹配。下面输入完整的标签来搜索
{
"query":{
"match":{
"labels_cn": "精品课"
}
}
}
----------
"hits": [
{
"_index": "book1",
"_type": "_doc",
"_id": "HzPcJ4ABRHGvpe9lHeCW",
"_score": 0.18232156,
"_source": {
"book_name": "畅销书",
"labels": "1;2;3",
"labels_cn": "历史;中国;精品课",
"labels_en": "history;china;class quality"
}
}
]
复制代码
可以看到符合我们的预期了。