Big Plans of Xunsearch
======================

标识符含义：* 暂定未做；+ 已完成；= 正在做；- 取消

= 优化 task.cc 分为(db+db_a)时如果实时 update 某一条数据可能导致 docid 修改而 cache 扔起作用会出现空白内容

+ 优化 task.cc 让 queryparser 可以复用与共享

+ 优化日志，减少输出，记录错误为主；增加状态监控模块，各个进程的详细情况。
  当前连接数，已处理请求数，最大并发数等……

+ 支持为每个项目分配自定义词库，只要项目目录下的 etc/ 目录存在？

+ 优化 xapian 的 queryparser 让它具备清除 prefix 等初始化功能
  避免新建对象

+ 增加同义词搜索、管理功能

+ Xapian 底层支持自定义文本词库，要求 txt 格式即可

+ 将代码使用 git 管理，并推送一份到 github 上托管

+ 设置搜索工作线程的超时时间

  某些搜索线程由于某些原因导致阻塞或死锁等问题长时间无法结束工作，
  从而造成 too many opened files 以及更严重的资源消耗问题。

  已完成，在线程池中标识每个线程的任务起始时间，然后由主线程调用检测函数来巡视。


+ 解决复合长词的搜索问题

  比如在搜索 “异常管理制度” 时经过分词后相当于检索 “异常、管理制度” 这 2 个词。
  这种情况并不是在所有场合都适合，用户可能更希望能检索“异常、管理、制度”三个词。
  
  可以考虑把默认词典中这类复合长词统统删除，而只保留短词。

+ 改进线程池

  每个线程均不能忽略某些信号 (SIGFPE、SIGILL、SIGBUS、SIGSEGV)，
  必须由收到信号的线程自行处理并中断运行。

  线程池中的工作线程异常引发 signal 从而调用 tpool_destroy() 时不要直接试图
  cancel 自己并等待结束，这样就会造成死等。

+ 优化信号处理

  signal_child() 中 status 参数依据 waitpid() 的 man 说明，
  应当调用相应的宏提取进程实际终止字。即：WIFEXITED()、WIFSIGNALED()
  此外还应还原 SIGFPE、SIGILL、SIGBUS、SIGSEGV 的默认行为以便导出 core 文件。

+ 关于 zcmd_exec_*** 回调函数的返回值

  除了 CMD_RES_UNIMP 外，其它的响应数据均由回调函数自行处理。
  至于是否结束连接则由上层调用统一根据返回值处理，勿在处理函数中直接调用 conn_quit，
  这会直接销毁整个 conn 结构从而引发不可预知的后果。

  增加特殊返回值 CMD_RES_NEXT 表示让其它默认和全局处理函数继续处理该指令。

+ 改进线程善后调用

  当前的服务器模型当出现异常退出时，没有为各连接善后，只有处于任务中的线程有机会cleanup()
  其它的连接在 exit() 后就直接退出了。不过由于进程已经终止，所有资源应当由系统直接回收了。

+ 远程数据库解决方案

  采用 stub 文件库数据库，其它路径则在目录底下创建软连接

+ 搜索线程中屏蔽 USE 指令切换项目

  当搜索服务器连接工作在线程中时，如果切换项目用户，当前的 zarg 内容就对不上了 (主要是 ->db 之类的指针)，
  实际使用中不太可能有这样的作法但应考虑从程序层面避免这类情况。考虑把 conn_zcmd_exec handlers 
  执行顺序调整一下，让指定的 handler 最先执行，以便提前返回 wrongplace 。

* 优化缓存设计方案

  当前缓存是用 MD5 (用户名+查询字符串) 作为键值，这样做就只能对默认库做缓存，如果再经过一番
  set_db/add_db 就不对了。

  缓存有效与否目前根据 db.get_doccount() 来判断，严格讲应该加入 last_docid 来加强判断。

+ 平滑重建索引

  原先重建索引均是先清空旧的索引然后依次从头加入数据，这样做的弊端在于会有一个时间段索引被中断，
  严重影响搜索体验，应当改为平滑过渡。

  同时注意重建期间的 clean 操作(直接禁用?)，以免交叉操作引起 bug，
  注意多个 conn 同时发出这个请求的情况时会交叉起作用。

+ 索引切割优化

  目前每个项目的索引数据全部集中在统一的一个 db 中，当数据量比较大时会导致更新速度极慢，
  需要适当切割优化同时又保证前端一致。(从 xs-import 入手?) 需要通过 xs_import、xs_searchd、xs_index 
  三者有机配合实现 DB 自动切分功能，然后通过 xs-import 特殊的退出字来表示是否需要进行合并。

* 改进 indexd 的 signal_child

  目前承担的工作过多，不宜在信号中出现过多可能导致阻塞的操作，而应适当记录 flag 便立即返回。

+ 让 CMD_DOC_TERM 支持 stemmer

  目前这条指令只是简单的添加一个词，而没有考虑 stemmer 的支持，
  在引入自定义分词器后显得很有必要加入此功能 (xs-import)，还应支持 posting 。

* 改进搜索返回的高亮词

  默认搜索时由于启用 stemmer 结果记录中可能存在一些词性不统一的匹配词未能正确高亮，
  比如搜索 works ，而匹配的结果里却只是包含  working 可以在返回结果里补足高亮词表来解决。

* 技术、理论背景及算法文档

+ 整合 charset 字符集

  已改进由 xs 对象控制一个默认的字符集，而 XSDocument 和 XSSsearch 也可单独指定字符集。

+ 在 XSSearch 整合相关、热门搜索及搜索建议或修正
  需要自动记录搜索日志，简化提取词汇进行记录，而不是原样记录那样太多垃圾词汇了。
  展开搜索完全要求前缀，拼音只支持少量几个字就好了吧，
  复合纠错也需要重点考虑深入搜索由于需要客户端加装 scws 扩展其实可以废除了，只保留相关搜索即可。

+ 设计 C++ 的工具程序 xs-logging 用于处理上述功能

  log_db 的内容:
  0) 字段结构: 完整内容存在 data 区.
     0:A. key,   主键, 小写的完整内容
     1:B. pinyin,全拼、缩写索引, 类似 parts 作法
        字数较短的全拼存入 spelling 以便模糊检索（0+raw), 针对整段完整的小拼音进行模糊音修正
     2:C. partial, 用于展开搜索的, 最多索引 MAX_EXPAND_LEN(global.h) 个字节, 
               超出部分用 wildcard 做法来解决
     3:D. total, 总计次数, 历史累计
     4:E. last_num, 上轮计数(用于统计近期)
     5:F. curr_num, 本轮计算
     6:G. curr_tag, 本轮标记, 如果标记不匹配则将 set last_num = curr_num, curr_num = 1, total+1
     
  1) 默认检索库中的主要词表 (allterms)

  2) 用户的搜索日志, 净化处理如下:
     A. 过滤无效字符并智能组合
     B. 消除英文与中文之间的多余空格
     C. 最多保留3~4个词的组合, 最长 48个字节(折合16个汉字)

  spelling和模糊音仅针对3个字和2个字的完整音节, 含前缀
  用户输入的模糊音纠错也只针对可识别的完整音节(非转换的 PY_CHINESE)?

  -- 模糊音在搜索时考虑 -- 
  如用户输入: zongguo 但匹配数据较少则自动尝试转换为 zhongguo 
  如用户输入: zhonguo 则会先修正为 zhongguo 如数据少则模糊修正为 zongguo 进行检索  

  检索词扩展做法 (输入信息: query)

  1. 净化 query 信息, 删除多余的空格, 并记录尾部是否带空格(如果有到时适当加权)

  >>2. 如果长度 > MAX_EXPAND_LEN(global.h), 直接用 wildcard 方式扩展检索 A 字段
       若纯英文同时尝试展开 pinyin 字段

  >>3. 如果纯中文, 则检索 parts:query 加权 parts:query + ' '

  4. 检索 parts:query (+权 parts:query + ' ')
     如果纯英文: 检测 pinyin:query 是否存在, 若不存在尝试用 spelling 修正先(修正后当作拼音继续检索)
                +OR pinyin:query  若数量少 
				+(若为完整拼音则尝试进行模糊修正 +OR pinyin:query2
     若包含中文: 
     全部转换为拼音如果长度 <= MAX_EXPAND_LEN(global.h), + OR pinyin:query2 

  检索词自动纠错做法(仅针对匹配少的词汇):

  1. 净化 query 信息, 删除多余的空格, 按空格分段 [单字的强行组合起来?]

  2. >>如果全部是英文, 消除所有空格尝试进行全拼(+模糊修正,+spelling修正)，缩写纠错, 英文纠错...

  3. 分段进行修正
  
     英文的话: 
       长度: <= MAX_EXPAND_LEN(global.h)
       如果是存在的拼音进行拼音检索 (pinyin:xxx) 检索, 其它的先进行 spelling 纠错
       再判断是否为拼音, 如是拼音则继续检索拼音, 如不是则直接输出 英文原样 (长度<=

       上面的尝试失败后, 则对于长段拼音适当进行分段纠错, 最多纠错 2个同音词, 除非频率
       接近否则直接彩用最高频的那个, 纠错失败的单字则确认略不显示

    中文的话进行拼音转换后查找更高频率的同音词, 如果没有则保持原样.

