mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-16 15:47:58 +00:00
Merge pull request #2495 from lonvia/fix-normalization-in-php
ICU: use correct normalization during search
This commit is contained in:
@@ -9,7 +9,6 @@ import re
|
|||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
|
||||||
from nominatim.db.connection import connect
|
from nominatim.db.connection import connect
|
||||||
from nominatim.db.properties import set_property, get_property
|
|
||||||
from nominatim.db.utils import CopyBuffer
|
from nominatim.db.utils import CopyBuffer
|
||||||
from nominatim.db.sql_preprocessor import SQLPreprocessor
|
from nominatim.db.sql_preprocessor import SQLPreprocessor
|
||||||
from nominatim.indexer.place_info import PlaceInfo
|
from nominatim.indexer.place_info import PlaceInfo
|
||||||
@@ -36,7 +35,6 @@ class LegacyICUTokenizer(AbstractTokenizer):
|
|||||||
self.dsn = dsn
|
self.dsn = dsn
|
||||||
self.data_dir = data_dir
|
self.data_dir = data_dir
|
||||||
self.loader = None
|
self.loader = None
|
||||||
self.term_normalization = None
|
|
||||||
|
|
||||||
|
|
||||||
def init_new_db(self, config, init_db=True):
|
def init_new_db(self, config, init_db=True):
|
||||||
@@ -47,8 +45,6 @@ class LegacyICUTokenizer(AbstractTokenizer):
|
|||||||
"""
|
"""
|
||||||
self.loader = ICURuleLoader(config)
|
self.loader = ICURuleLoader(config)
|
||||||
|
|
||||||
self.term_normalization = config.TERM_NORMALIZATION
|
|
||||||
|
|
||||||
self._install_php(config.lib_dir.php)
|
self._install_php(config.lib_dir.php)
|
||||||
self._save_config()
|
self._save_config()
|
||||||
|
|
||||||
@@ -64,7 +60,6 @@ class LegacyICUTokenizer(AbstractTokenizer):
|
|||||||
|
|
||||||
with connect(self.dsn) as conn:
|
with connect(self.dsn) as conn:
|
||||||
self.loader.load_config_from_db(conn)
|
self.loader.load_config_from_db(conn)
|
||||||
self.term_normalization = get_property(conn, DBCFG_TERM_NORMALIZATION)
|
|
||||||
|
|
||||||
|
|
||||||
def finalize_import(self, config):
|
def finalize_import(self, config):
|
||||||
@@ -87,13 +82,9 @@ class LegacyICUTokenizer(AbstractTokenizer):
|
|||||||
def check_database(self, config):
|
def check_database(self, config):
|
||||||
""" Check that the tokenizer is set up correctly.
|
""" Check that the tokenizer is set up correctly.
|
||||||
"""
|
"""
|
||||||
|
# Will throw an error if there is an issue.
|
||||||
self.init_from_project(config)
|
self.init_from_project(config)
|
||||||
|
|
||||||
if self.term_normalization is None:
|
|
||||||
return "Configuration for tokenizer 'icu' are missing."
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def update_statistics(self):
|
def update_statistics(self):
|
||||||
""" Recompute frequencies for all name words.
|
""" Recompute frequencies for all name words.
|
||||||
@@ -141,7 +132,7 @@ class LegacyICUTokenizer(AbstractTokenizer):
|
|||||||
php_file.write_text(dedent(f"""\
|
php_file.write_text(dedent(f"""\
|
||||||
<?php
|
<?php
|
||||||
@define('CONST_Max_Word_Frequency', 10000000);
|
@define('CONST_Max_Word_Frequency', 10000000);
|
||||||
@define('CONST_Term_Normalization_Rules', "{self.term_normalization}");
|
@define('CONST_Term_Normalization_Rules', "{self.loader.normalization_rules}");
|
||||||
@define('CONST_Transliteration', "{self.loader.get_search_rules()}");
|
@define('CONST_Transliteration', "{self.loader.get_search_rules()}");
|
||||||
require_once('{phpdir}/tokenizer/icu_tokenizer.php');"""))
|
require_once('{phpdir}/tokenizer/icu_tokenizer.php');"""))
|
||||||
|
|
||||||
@@ -152,7 +143,6 @@ class LegacyICUTokenizer(AbstractTokenizer):
|
|||||||
"""
|
"""
|
||||||
with connect(self.dsn) as conn:
|
with connect(self.dsn) as conn:
|
||||||
self.loader.save_config_to_db(conn)
|
self.loader.save_config_to_db(conn)
|
||||||
set_property(conn, DBCFG_TERM_NORMALIZATION, self.term_normalization)
|
|
||||||
|
|
||||||
|
|
||||||
def _init_db_tables(self, config):
|
def _init_db_tables(self, config):
|
||||||
|
|||||||
@@ -3,6 +3,31 @@ Feature: Import and search of names
|
|||||||
Tests all naming related issues: normalisation,
|
Tests all naming related issues: normalisation,
|
||||||
abbreviations, internationalisation, etc.
|
abbreviations, internationalisation, etc.
|
||||||
|
|
||||||
|
Scenario: non-latin scripts can be found
|
||||||
|
Given the places
|
||||||
|
| osm | class | type | name |
|
||||||
|
| N1 | place | locality | Речицкий район |
|
||||||
|
| N2 | place | locality | Refugio de montaña |
|
||||||
|
| N3 | place | locality | 高槻市|
|
||||||
|
| N4 | place | locality | الدوحة |
|
||||||
|
When importing
|
||||||
|
When sending search query "Речицкий район"
|
||||||
|
Then results contain
|
||||||
|
| ID | osm |
|
||||||
|
| 0 | N1 |
|
||||||
|
When sending search query "Refugio de montaña"
|
||||||
|
Then results contain
|
||||||
|
| ID | osm |
|
||||||
|
| 0 | N2 |
|
||||||
|
When sending search query "高槻市"
|
||||||
|
Then results contain
|
||||||
|
| ID | osm |
|
||||||
|
| 0 | N3 |
|
||||||
|
When sending search query "الدوحة"
|
||||||
|
Then results contain
|
||||||
|
| ID | osm |
|
||||||
|
| 0 | N4 |
|
||||||
|
|
||||||
Scenario: Case-insensitivity of search
|
Scenario: Case-insensitivity of search
|
||||||
Given the places
|
Given the places
|
||||||
| osm | class | type | name |
|
| osm | class | type | name |
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import yaml
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from nominatim.tokenizer import icu_tokenizer
|
from nominatim.tokenizer import icu_tokenizer
|
||||||
from nominatim.tokenizer.icu_rule_loader import ICURuleLoader
|
import nominatim.tokenizer.icu_rule_loader
|
||||||
from nominatim.db import properties
|
from nominatim.db import properties
|
||||||
from nominatim.db.sql_preprocessor import SQLPreprocessor
|
from nominatim.db.sql_preprocessor import SQLPreprocessor
|
||||||
from nominatim.indexer.place_info import PlaceInfo
|
from nominatim.indexer.place_info import PlaceInfo
|
||||||
@@ -75,7 +75,7 @@ def analyzer(tokenizer_factory, test_config, monkeypatch,
|
|||||||
'token-analysis': [{'analyzer': 'generic',
|
'token-analysis': [{'analyzer': 'generic',
|
||||||
'variants': [{'words': list(variants)}]}]}
|
'variants': [{'words': list(variants)}]}]}
|
||||||
(test_config.project_dir / 'icu_tokenizer.yaml').write_text(yaml.dump(cfgstr))
|
(test_config.project_dir / 'icu_tokenizer.yaml').write_text(yaml.dump(cfgstr))
|
||||||
tok.loader = ICURuleLoader(test_config)
|
tok.loader = nominatim.tokenizer.icu_rule_loader.ICURuleLoader(test_config)
|
||||||
|
|
||||||
return tok.name_analyzer()
|
return tok.name_analyzer()
|
||||||
|
|
||||||
@@ -151,13 +151,12 @@ def getorcreate_hnr_id(temp_db_cursor):
|
|||||||
SELECT -nextval('seq_word')::INTEGER; $$ LANGUAGE SQL""")
|
SELECT -nextval('seq_word')::INTEGER; $$ LANGUAGE SQL""")
|
||||||
|
|
||||||
|
|
||||||
def test_init_new(tokenizer_factory, test_config, monkeypatch, db_prop):
|
def test_init_new(tokenizer_factory, test_config, db_prop):
|
||||||
monkeypatch.setenv('NOMINATIM_TERM_NORMALIZATION', ':: lower();')
|
|
||||||
|
|
||||||
tok = tokenizer_factory()
|
tok = tokenizer_factory()
|
||||||
tok.init_new_db(test_config)
|
tok.init_new_db(test_config)
|
||||||
|
|
||||||
assert db_prop(icu_tokenizer.DBCFG_TERM_NORMALIZATION) == ':: lower();'
|
assert db_prop(nominatim.tokenizer.icu_rule_loader.DBCFG_IMPORT_NORM_RULES) \
|
||||||
|
.startswith(':: lower ();')
|
||||||
|
|
||||||
|
|
||||||
def test_init_word_table(tokenizer_factory, test_config, place_row, temp_db_cursor):
|
def test_init_word_table(tokenizer_factory, test_config, place_row, temp_db_cursor):
|
||||||
@@ -171,17 +170,14 @@ def test_init_word_table(tokenizer_factory, test_config, place_row, temp_db_curs
|
|||||||
assert temp_db_cursor.table_exists('word')
|
assert temp_db_cursor.table_exists('word')
|
||||||
|
|
||||||
|
|
||||||
def test_init_from_project(monkeypatch, test_config, tokenizer_factory):
|
def test_init_from_project(test_config, tokenizer_factory):
|
||||||
monkeypatch.setenv('NOMINATIM_TERM_NORMALIZATION', ':: lower();')
|
|
||||||
tok = tokenizer_factory()
|
tok = tokenizer_factory()
|
||||||
tok.init_new_db(test_config)
|
tok.init_new_db(test_config)
|
||||||
monkeypatch.undo()
|
|
||||||
|
|
||||||
tok = tokenizer_factory()
|
tok = tokenizer_factory()
|
||||||
tok.init_from_project(test_config)
|
tok.init_from_project(test_config)
|
||||||
|
|
||||||
assert tok.loader is not None
|
assert tok.loader is not None
|
||||||
assert tok.term_normalization == ':: lower();'
|
|
||||||
|
|
||||||
|
|
||||||
def test_update_sql_functions(db_prop, temp_db_cursor,
|
def test_update_sql_functions(db_prop, temp_db_cursor,
|
||||||
|
|||||||
Reference in New Issue
Block a user