通过Solr的Suggest实现提示词

阅读更多
需求:在Web端或移动设备上实现用户输入汉字或汉字的首字母,提供关联词提示。

解决方案:通过Solr提供的Suggest实现此功能,Solr版本为4.10.4

在Solr的配置文件solrconfig.xml文件中修改Suggest的配置,通过提示词文件构建搜索索引:



  mySuggester
  AnalyzingLookupFactory
  FileDictionaryFactory
  suggest
  suggest.txt
  string
  false




  true
  5


  suggest



参数说明:
name:suggester的名字,如果设置多个,可以在请求中指定。
lookupImpl:查找方式的具体实现
dictionaryImpl:字典的具体实现
field:搜索的字段
sourceLocation:字典文件
suggestAnalyzerFieldType:字段的类型
buildOnOptimize:何时创建拼写索引
suggest.count:返回的搜索结果的数量

因为要同时提供汉字和汉字拼音首字母的搜索,因此在构建字典文件时需要进行特殊处理,字典文件样例如下:

abesb|阿巴二氏病
阿巴二氏病|abesb
abkw|阿巴卡韦
阿巴卡韦|abkw
abkwsfd|阿巴卡韦双夫定
阿巴卡韦双夫定|abkwsfd
abkwsfdp|阿巴卡韦双夫定片
阿巴卡韦双夫定片|abkwsfdp


这样做就从业务需求上可以满足,但索引量成倍增多,在数据量不是特别大的时候性能问题基本可以忽略。
搜索测试的链接如下:
http://127.0.0.1:8080/solr/metis/suggest?qt=suggest&suggest.dictionary=mySuggester&wt=json&suggest.q=天
返回结果如下:

{
- responseHeader:  {
    - status: 0,
    - QTime: 1
- },
- suggest:  {
    - mySuggester:  {
        - 天:  {
            - numFound: 5,
            - suggestions:  [
                - {
                    - term: "天一止咳|tyzk",
                    - weight: 1,
                    - payload: ""
                - },
                - {
                    - term: "天一止咳糖浆|tyzktj",
                    - weight: 1,
                    - payload: ""
                - },
                - {
                    - term: "天丹通络|tdtl",
                    - weight: 1,
                    - payload: ""
                - },
                - {
                    - term: "天丹通络胶囊|tdtljn",
                    - weight: 1,
                    - payload: ""
                - },
                - {
                    - term: "天仙藤|txt",
                    - weight: 1,
                    - payload: ""
                - }
            - ]
        - }
    - }
- }
}


页面上通过jQuery的Autocomplete功能实现。
页面代码如下:




    
    Hello World!
    
    
    
    



JavaScript部分的代码如下,需要对搜索结果的词进行格式化,这部分功能也可以通过后端实现,但性能没有前端从Solr获取结果处理快:

const http = require('http'),
    qs = require('querystring');

var Suggest = exports;

Suggest.search = function (keyword) {
    var data = {
        qt: 'suggest',
        'suggest.dictionary': 'mySuggester',
        'wt': 'json',
        'suggest.q': keyword
    };

    var content = qs.stringify(data);

    var options = {
        hostname: '127.0.0.1',
        port: 8080,
        path: '/solr/metis/suggest?' + content,
        method: 'GET'
    };

    var result = [];
    var promise = new Promise(function (resolve, reject) {
        var req = http.request(options, function (res) {
            res.on('data', function (chunk) {
                result = convert(keyword, chunk);
                resolve(result);
            });
        });

        req.on('error', function (e) {
            reject(new Error(e.message));
        });

        req.end();
    });

    return promise;
};

function convert(keyword, data) {
    var result = [];
    var json = JSON.parse(String(data));
    var num = parseInt(json.suggest.mySuggester[keyword].numFound);
    if (num > 0) {
        var matcher = new RegExp("^[A-Za-z0-9]+$", "i");
        var tmp = json.suggest.mySuggester[keyword].suggestions;
        for (var i = 0; i < tmp.length; i++) {
            var d = tmp[i]['term'].split('\|');
            if (matcher.test(d[0])) {
                var obj = {
                    label: d[0],
                    value: d[1]
                };
                result.push(obj);
            } else {
                result.push(d[0]);
            }
        }
    }

    return result;
}

你可能感兴趣的:(solr,json,javascript)