Solr6.6总结(二)功能测试

来源:互联网 发布:行省制的影响知乎 编辑:程序博客网 时间:2024/06/07 08:47

基于上一篇的环境http://blog.csdn.net/u011562187/article/details/77720975

今天也做了很多solr在PHP下的测试,学到不少东西。先把昨天java测试环境说一下,再说PHP的。

solr Java客户端环境

1,新建一个java项目;
2.将solr-6.6.0\dist\solrj-lib下的jar包复制到项目lib目录下,将solr-6.6.0\dist下的solr-solrj-6.6.0.jar复制到lib目录下,把所有jar包add to build path;
3编写代码测试,目录结构和代码如下图
这里写图片描述

java增删改查的具体写法在这里就不说了,因为主要要讲PHP的。

Solr PHP环境

通过官方文档https://wiki.apache.org/solr/IntegratingSolr,我们可以看到各个语言如何集成solr客户端。
PHP的第三方lib也有很多,
这里写图片描述
我这里随便选了第一个solarium,谁叫他放第一个呢。
然后找到 http://www.solarium-project.org/ 和github网址 https://github.com/solariumphp/solarium
我先把github项目下下来,运行sample。需要composer。
下下来之后我解压到solariumsample下,运行composer install,会自动下载依赖,下好之后目录如下
这里写图片描述
然后修改examples目录下的config.dist.php配置文件,solr服务器的host,port和path,注意默认的path是/solr是不对了,应该到core层。

<?php$config = array(    'endpoint' => array(        'localhost' => array(            'host' => '127.0.0.1',            'port' => 8080,            'path' => '/solr/new_core',        )    ));

配置php服务器环境,然后访问examples下的index.html
http://localhost:8090/examples/index.html 就可以查看demo了,点击check-solarium-and-ping应该出现如下界面
这里写图片描述

然后我在另一个Thinkphp项目下安装环境,直接在项目根目录下命令行运行

composer require solarium/solarium

就会下载相关依赖。
在某个controller下写了如下测试代码

config.php下添加如下配置    'SOLR_CONFIG'=>array(        'endpoint' => array(            'localhost' => array(                'host' => '127.0.0.1',                'port' => 8080,                'path' => '/solr/new_core',            )        )    ),

提取文件内容到solr供搜索

    /**     * 添加文件     */    public function testAddFile()    {        //创建client        require '/vendor/autoload.php';        $client = new \Solarium\Client(C('SOLR_CONFIG'));        //创建一个提取查询        $query = $client->createExtract();        //项目Uploads/solr目录下有一个测试doc文件        $query->setFile($_SERVER['DOCUMENT_ROOT'] . "/Uploads/solr/test.docx");        //solr会将文件的额外信息保存到attr开头的字段中,为什么是attr,这个是和managed-schema文件配置相关的,field,dynamicField,copyField        //你也可以不要这句测试一下看看什么结果,还有一些其他设置也可以自行测试下        $query->setUprefix("attr_");        //$query->addParam("literal.id", "10000");跟下面的$doc->id = '10000';效果一样,设置id,id是必须的。        $query->addParam("fmap.content", "attr_content");//文件内容content映射成attr_content        //$query->setExtractOnly(false);//默认就是false,设置为true的话就只提取文件内容,然后返回(response中获取内容),而不会添加到solr数据中        $doc = $query->createDocument();        $doc->id = '10000';//id不存在是add,id存在是update        $doc->title = '这是我的测试标题';//设置额外的字段        $query->setDocument($doc);        $query->setCommit(true);        //$query->setOmitHeader(false);        $result = $client->extract($query);//        echo 'Add status: ' . $result->getStatus() . '<br/>';        //StatusCode为200表示成功        echo 'Add status: ' . $result->getResponse()->getStatusCode() . '<br/>';    }

上传结果:
这里写图片描述
服务器后台查询
这里写图片描述
(你可能看到了一个searchkey字段,这个字段我们稍后讨论,solr的配置选项挺多,需要不停优化)

删除solr数据

    public function testDel()    {        require '/vendor/autoload.php';        $client = new \Solarium\Client(C('SOLR_CONFIG'));        $query = $client->createUpdate();        //还记得添加的时候必须设置id吗,可以按id删除,查询删除等        $query->addDeleteById("10000");        //$query->addDeleteQuery("*:*");//删除所有        $query->addCommit();        $result = $client->update($query);        echo 'Delete status: ' . $result->getStatus() . '<br/>';    }

删除结果
这里写图片描述
在查询一下,已经没有了
这里写图片描述

客户端查询

  public function testQuery()    {        require '/vendor/autoload.php';        $client = new \Solarium\Client(C('SOLR_CONFIG'));        $query = $client->createSelect();        //$query->setQuery("*:*");//查询所有//        $query->setQuery("searchkey:技术");//下面解释        $query->setQuery("title:测试");        //$query->addFilterQuery()//多重条件,还没怎么测试        //返回那些字段,不设置就是所有        $query->setFields("id,title,attr_content");        //分页        $query->setStart(0);        $query->setRows(10);        //高亮相关搜索词        $hl = $query->getHighlighting();        $hl->setFields('title, attr_content');        $hl->setSimplePrefix('<font color="red" >');        $hl->setSimplePostfix('</font>');// this executes the query and returns the result        $resultset = $client->select($query);        $highlighting = $resultset->getHighlighting();// display the total number of documents found by solr        echo 'NumFound: ' . $resultset->getNumFound();// show documents using the resultset iterator        foreach ($resultset as $document) {            echo '<hr/><table>';            // the documents are also iterable, to get all fields            foreach ($document as $field => $value) {                // this converts multivalue fields to a comma-separated string                if (is_array($value)) {                    $value = implode(', ', $value);                }                echo '<tr><th>' . $field . '</th><td>' . $value . '</td></tr>';            }            echo '</table><br/><b>Highlighting results:</b><br/>';            // highlighting results can be fetched by document id (the field defined as uniquekey in this schema)            $highlightedDoc = $highlighting->getResult($document->id);            if ($highlightedDoc) {                foreach ($highlightedDoc as $field => $highlight) {                    echo implode(' (...) ', $highlight) . '<br/>';                }            }        }    }

查询结果
这里写图片描述
(这里添加的时候,如何把doc文件前面的一些附加内容(date 2017-08-31T10:28:00Z cp:revision 5 extended-properties:AppVersion……)去掉,还不知道。我知道一种方式,就是extrat的时候,设置extractOnly为true,返回的response里面有一个值只有doc正文内容,然后再add到solr,但是我觉得是不是太麻烦了,是否有参数或者方法可以设置,还需在研究研究。)(9.4日更新,重新设置一遍后没有这个问题了,提取内容也正常了,还不确定是哪里的配置出了问题,WEB-INFO/lib目录下不能乱添东西)

再说说searchkey
我们搜索的时候可能要一个关键词对多个字段搜索,比如搜“计算机”,我们既要把标题中包含“计算机”的条目搜出来,也要把内容中包含计算机的条目搜出来。
我打开我的solr_home\new_core\conf下的managed-schema文件,如下,字段很多,没截全。
这里写图片描述
可以看到attr_*是dynamicField, 理解了所有匹配形式的都是dynamicField。
field就是些明确的字段
在客户端添加字段的时候,字段必须在这里有定义,明确的或匹配的,否则会报错字段不存在。
说到这儿后台的schema对应的就是这个文件中定义的字段和动态字段
这里写图片描述

copyfield是啥呢?
就是用于解决上面的问题。把source字段的内容,copy到dest字段。我这里把title字段copy到searchkey字段,把attr_content字段也copy到searchkey字段,添加的时候就会出现上面的searchkey字段,他是一个数组,包含title和attr_content,然后搜索的时候

$query->setQuery("searchkey:技术");

就可以搜索出title或者attr_content包含”技术”的内容了,结果如下
这里写图片描述

这里只是测试,没考虑效率问题,这里content很长,这样映射的话content的内容相当于存了2遍,存储的时候可能并没有存2遍,但至少传输打印的时候,传了2遍,所以肯定不好,知道道理了,自行优化。

还有些东西没说,也有些东西没研究好,如中文分词,搜索评分系统,搜索过滤,等等。比如我遇到,只搜索一个字母,返回的结果为空,我猜是匹配度太低,所以为空,但有时候我们可能又要这种结果,怎么配置和优化还要再研究。