PHP搜索功能中荷兰/德语复合词匹配问题求解
荷兰语复合词搜索的非类库解决方案
一、基于构词规则的精准匹配逻辑
针对荷兰语复合词的词根拼接特性,结合短词误匹配问题,设计分层匹配规则:
- 长搜索词(长度>2):直接匹配子串,但优先加权复合词的词根典型位置(如食材类复合词多以食材词根结尾,比如
zilvervliesrijst的rijst),同时排除完全独立的短词包含情况(依赖高频词根表)。 - 短搜索词(长度≤2,如
ei、ui):- 优先匹配完整单词(如
ei直接匹配ei,而非子串); - 若匹配子串,需满足任一条件:
- 子串位于目标字符串的开头/结尾(如
ei匹配eiwit开头,ui匹配uiroerbiet开头); - 子串前的字符是荷兰语复合词常见的连接元音/辅音(如
-e-、-s-,比如eiersaus中ei后接s属于复合词连接特征); - 排除本身是独立词根的词(如
prei包含ei,但prei是独立食材,直接跳过匹配)。
- 子串位于目标字符串的开头/结尾(如
- 优先匹配完整单词(如
二、轻量级词根-复合词映射表(自动构建)
无需手动拆分复合词,从现有数据中自动构建关联映射:
- 初始化核心词根库:从已整理的食材表中提取所有单字食材(如
rijst、ei、ui)作为核心词根; - 自动关联复合词:遍历所有文本字段(标题、菜系、厨具等),提取包含核心词根的长词,同时过滤掉本身属于独立词根的词(如
prei需提前加入排除列表); - 存储映射关系:将核心词根与关联的复合词存入映射表(如
rijst→zilvervliesrijst、pandanrijst),后续新增食谱时,用正则匹配核心词根,自动更新映射表。
搜索流程:
- 用户输入搜索词,先匹配核心词根库,若命中词根,再检索所有关联的复合词;
- 若输入的是复合词,反向匹配到核心词根,同时保留原词的完全匹配。
三、SQL层面的自定义匹配函数(覆盖多字段)
针对标题、菜系等未手动处理的字段,在SQL中实现自定义函数MATCH_COMPOUND嵌入上述规则:
CREATE FUNCTION MATCH_COMPOUND(search_term VARCHAR(255), target_str VARCHAR(255)) RETURNS BOOLEAN DETERMINISTIC BEGIN DECLARE term_len INT; SET term_len = LENGTH(search_term); -- 完全匹配优先 IF target_str LIKE CONCAT('% ', search_term, ' %') OR target_str = search_term THEN RETURN TRUE; END IF; -- 长词匹配逻辑 IF term_len > 2 THEN IF target_str LIKE CONCAT('%', search_term, '%') THEN -- 排除独立词根的包含 RETURN NOT EXISTS (SELECT 1 FROM root_words WHERE word = target_str); END IF; RETURN FALSE; END IF; -- 短词匹配逻辑 IF term_len <= 2 THEN -- 匹配开头/结尾 IF target_str LIKE CONCAT(search_term, '%') OR target_str LIKE CONCAT('%', search_term) THEN RETURN TRUE; END IF; -- 匹配连接特征后的子串 IF target_str LIKE CONCAT('%e', search_term, '%') OR target_str LIKE CONCAT('%s', search_term, '%') THEN RETURN TRUE; END IF; -- 排除独立词根的包含后再匹配子串 RETURN NOT EXISTS (SELECT 1 FROM root_words WHERE word = target_str) AND target_str LIKE CONCAT('%', search_term, '%'); END IF; RETURN FALSE; END;
查询调用示例:
SELECT * FROM recipes WHERE MATCH_COMPOUND('ei', title) OR MATCH_COMPOUND('ei', cuisine);
四、高频独立词根过滤
维护一个高频独立词根列表(如prei、spruitjes),这些词虽包含短搜索词,但本身是完整语义的独立词,搜索时直接排除这类匹配。该列表可从现有食谱数据中自动提取(筛选出现频率高、且不包含其他核心词根的词)。
内容的提问来源于stack exchange,提问作者Pepijn Ekelmans
相关产品推荐
相关产品推荐

