web.php5.sk

Elasticsearch - mapping IV

23. apríl 2020 / Čamo

V tejto časti sa pozrieme na zúbok tzv. charakter filtrom. Dobrú chuť.

Character filters

Character filters spracujú reťazec pred tým než sa dostane k tokenizeru

Character filter dostane originálny reťazec ako tok znakov a vykoná nad nim požadovanú operáciu ako napr. pridávanie/odstránenie znakov, odstránenie html tagov, convertovanie Hindu-Arabic čísel na Arabic-Latin ekvivalenty...

Elasticsearch má množstvo preddefinovaných charakter filtrov ktoré sa dajú použiť v custom analyzeroch.

 

HTML Strip Character Filter

HTML Strip Character Filter html_strip character odstráni html elementy z textu a nahradí html entity ich dekodovanou variantou napr. & za &

POST _analyze
{
  "tokenizer":      "keyword", 
  "char_filter":  [ "html_strip" ],
  "text": "<p>I&apos;m so <b>happy</b>!</p>"
}

Príklad vráti jeden token v tvare: \nI'm so happy!\n

Ak by sme použili standard tokenizer vrátil by tri tokeny: I'm, so, happy

Parametre html_strip character filtra

  • escaped_tags: Je to pole html tagov, ktoré nemajú byť odstránené z textu. 
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "keyword",
          "char_filter": ["my_char_filter"]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "html_strip",
          "escaped_tags": ["b"]
        }
      }
    }
  }
}

POST my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "<p>I&apos;m so <b>happy</b>!</p>"
}

Request z príkladu vráti token: \nI'm so <b>happy</b>!\n v ktorom je zachovaný tag <b>

 

Mapping Char Filter

Mapping character filter akceptuje asociatívne pole kde kľúč je hľadaný reťazec a hodnota je reťazec, ktorý sa vloží miesto neho. Vyhľadávanie je greedy tj. dlhší reťazec spomedzi hľadaných kľúčov sa použije k náhrade.

Parametre mapping char filtra

  • mappings: Pole dvojích key => value, kde key je hľadaný výraz a value je náhrada, ktorá sa vloží miesto neho.
  • mappings_path: Path buď absolútna alebo relatívna ku config directory, k UTF-8 súboru, ktorý obsahuje key => value mapping oddelený odriadkovaním. 
 

Jeden z predošlých parametrov musí byť uvedený. 

Príklad char_filtra

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "keyword",
          "char_filter": [
            "my_char_filter"
          ]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "mapping",
          "mappings": [
            "٠ => 0",
            "١ => 1",
            "٢ => 2",
            "٣ => 3",
            "٤ => 4",
            "٥ => 5",
            "٦ => 6",
            "٧ => 7",
            "٨ => 8",
            "٩ => 9"
          ]
        }
      }
    }
  }
}

POST my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "My license plate is ٢٥٠١٥"
}

Predošlý príklad vráti token: My license plate is 25015

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "standard",
          "char_filter": [
            "my_char_filter"
          ]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "mapping",
          "mappings": [
            ":) => _happy_",
            ":( => _sad_"
          ]
        }
      }
    }
  }
}

POST my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "I'm delighted about it :("
}
 

Predošlý príklad vráti tokeny: I'm, delighted, about, it, _sad_

 

Pattern Replace Char Filter

Pattern replace filter character filter používa regulárny výraz namiesto hľadaných reťazcov. Nahradzovaný výraz môže odkazovať na skupinu znakov zachatený regulárnym výrazom.

Elasticsearch používa Java Regular Expressions.

Parametre pre pattern_replace filter

  • pattern: Java Regular Expressions
  • replacement: Náhradný reťazec. Náhradný reťazec môže odkazovať na skupinu znakov zachytenú reg. výrazom viď link
  • flags: Java regular expression flags. Flags sa oddeľujú pipou | napr. CASE_INSENSITIVE|COMMENTS
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "standard",
          "char_filter": [
            "my_char_filter"
          ]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "pattern_replace",
          "pattern": "(\\d+)-(?=\\d)",
          "replacement": "$1_"
        }
      }
    }
  }
}

POST my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "My credit card is 123-456-789"
}

V predošlom príklade sme definovali pattern_replace filter ktorý zamení pomlčky v číslach za podtržítka. Request vráti tokeny: My, credit, card, is, 123_456_789

Nasledujúci príklad pridáva medzeru ak narazí na sekvenciu znakov kde malé písmeno nasleduje veľké písmeno (fooBarBaz → foo Bar Baz), čo umožní camelCase výrazy vyhľadávať samostatne

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "standard",
          "char_filter": [
            "my_char_filter"
          ],
          "filter": [
            "lowercase"
          ]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "pattern_replace",
          "pattern": "(?<=\\p{Lower})(?=\\p{Upper})",
          "replacement": " "
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "properties": {
        "text": {
          "type": "text",
          "analyzer": "my_analyzer"
        }
      }
    }
  }
}

POST my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "The fooBarBaz method"
}

Predošlý request vráti tokeny: the, foo, bar, baz, method

Request na výraz bar vráti správny dokument ALE highlighting nad výsledkom nebude fungovať správne, pretože character filter zmení dlžku originálneho textu

PUT my_index/_doc/1?refresh
{
  "text": "The fooBarBaz method"
}

GET my_index/_search
{
  "query": {
    "match": {
      "text": "bar"
    }
  },
  "highlight": {
    "fields": {
      "text": {}
    }
  }
}

Predošlý request vráti nasledujúci result všimnite si chybu vo zvýrazňovaní

{
  "timed_out": false,
  "took": $body.took,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped" : 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.2876821,
        "_source": {
          "text": "The fooBarBaz method"
        },
        "highlight": {
          "text": [
            "The foo<em>Ba</em>rBaz method" 
          ]
        }
      }
    ]
  }
}
Ak chcete pridávať komentáre musíte sa prihlásiť