ik分词器扩展


// 1. 扩展IK原生词典类(关键改造点)
public class HotDict extends Dictionary {
    private static final CopyOnWriteArrayList HOT_WORDS = new CopyOnWriteArrayList<>();
    
    // 动态加载新词到内存
    public static void reload(String filePath) {
        try {
            List newWords = Files.readAllLines(Paths.get(filePath));
            HOT_WORDS.clear();
            HOT_WORDS.addAll(newWords);
            logger.info("热词库已更新,数量:{}", HOT_WORDS.size());
        } catch (IOException e) {
            logger.error("热词库加载失败", e);
        }
    }

    // 重写IK词库加载方法
    @Override
    public void loadMainDict() {
        super.loadMainDict(); // 加载主词典
        HOT_WORDS.forEach(super::addWord); // 加载热词
    }
}
// 2. 文件变更监听组件
@Component
public class DictFileWatcher {
    @Value("${hotdict.path:hot_words.txt}")
    private String dictPath;

    @PostConstruct
    public void init() {
        WatchService watcher = FileSystems.getDefault().newWatchService();
        Paths.get(".").register(watcher, ENTRY_MODIFY);
        
        new Thread(() -> {
            while (true) {
                WatchKey key = watcher.take();
                for (WatchEvent event : key.pollEvents()) {
                    if (event.context().toString().equals(dictPath)) {
                        HotDict.reload(dictPath); // 触发热加载
                    }
                }
                key.reset();
            }
        }).start();
    }

// 3. 分词器配置(Spring集成)
@Configuration
public class IKConfig {
    
    @Bean
    public Analyzer ikAnalyzer() {
        return new Analyzer() {
            @Override
            protected TokenStreamComponents createComponents(String fieldName) {
                // 使用改造后的词典
                HotDict.loadMainDict(); 
                return new TokenStreamComponents(new IKTokenizer());
            }
        };
    }
}

2. **调用分词API**
   ```java
   @RestController
   public class TestController {
       @Autowired Analyzer analyzer;
       
       @GetMapping("/split")
       public List split(@RequestParam String text) throws IOException {
           List result = new ArrayList<>();
           TokenStream stream = analyzer.tokenStream("", text);
           stream.reset();
           while (stream.incrementToken()) {
               CharTermAttribute term = stream.getAttribute(CharTermAttribute.class);
               result.add(term.toString());
           }
           return result;
       }
   }

3. **验证初始效果*
   // 避免加载过程中出现空指针
   private static volatile List activeWords = new ArrayList<>();
   private static List standbyWords = new ArrayList<>();

   public static void reload() {
       standbyWords.clear();
       standbyWords.addAll(loadNewWords());
       List temp = activeWords;
       activeWords = standbyWords;
       standbyWords = temp; // 原子切换
   

3. **HTTP-API触发更新**
   ```java
   @PostMapping("/reload-dict")
   public String reloadDict(@RequestParam String token) {
       if (!validToken(token)) return "forbidden";
       HotDict.reload();
       return "success";
   }

4. **性能监控**
   ```java
   // 记录加载耗时
   Long start = System.currentTimeMillis();
   HotDict.reload();
   Metrics.timer("dict_reload").record(System.currentTimeMillis() - start)

你可能感兴趣的:(elasticsearch)