为你的网站添加强大的搜索功能

优质
小牛编辑
133浏览
2023-12-01

elasticSearch安装

elasticSearch服务的安装请见我的上一篇文章《教你成为全栈工程师(Full Stack Developer) 二十四-ES(elasticsearch)搜索引擎安装和使用

elastic-bundle插件安装

需要在我们的symfony2项目中安装elastic-bundle插件,执行

[root@centos7vm mywebsite]# composer require friendsofsymfony/elastica-bundle

配置方法

修改app/AppKernel.php添加如下注册:

new FOS\ElasticaBundle\FOSElasticaBundle(),

并在app/config/config.yml中添加

fos_elastica:
    clients:
        default: { host: localhost, port: 9200 }
    indexes:
        app:
            types:
                blogpost:
                    mappings:
                        title:
                            type: string
                            index: analyzed
                            analyzer: ik_max_word
                        body:
                            type: string
                            index: analyzed
                            analyzer: ik_max_word
                    persistence:
                        driver: orm
                        model: AppBundle\Entity\BlogPost
                        provider: ~
                        listener:
                            insert: true
                            update: true
                            delete: true
                        finder: ~

解释一下

这里的clients配置的是本地elasticSearch服务的host和port

app是我们应用的名字,你可以随意改成你指定的名字,比如shareditor

blogpost是我们应用里不同数据的名字,每一个都会把索引集中建到一起

title和body是我们要搜索的域,这里我们指定了切词器是ik_max_word

persistence里配置了blogpost的读取orm,也就是BlogPost这个Entity

批量生成索引

执行

[root@centos7vm mywebsite]# php app/console fos:elastica:populate

ps:这一句只在第一次集成elasticSearch的时候执行,以后每当有新文章发布就会自动写入索引,无需手动更新

下面我们开始修改网站添加搜索功能

添加action

修改src/AppBundle/Controller/BlogController.php,增加如下方法:

    public function searchAction(Request $request)
    {
        $query = $request->get('q');
        $finder = $this->container->get('fos_elastica.finder.app.blogpost');
        $paginator = $this->get('knp_paginator');
        $results = $finder->createPaginatorAdapter($query);
        $pagination = $paginator->paginate($results, 1, 10);
        return $this->render('blog/search.html.twig', array('pagination' => $pagination,
            'query' => $query,
            'latestblogs' => BlogController::getLatestBlogs($this),
            'recommends' => BlogController::getRecommends($this)));
    }

解释一下

$request->get('q');这是从url参数里获取q这个参数来作为query词,后面网页修改里会通过form表单的input空间传递q的value

$this->container->get('fos_elastica.finder.app.blogpost');这是根据config.yml里的配置获取finder实例来做搜索用

下面利用$paginator做翻页,每页10条,默认展示第一页

添加路由配置

修改app/config/routing.yml,添加

blog_search:
    path:     /blogsearch
    defaults: { _controller: AppBundle:Blog:search }

修改网页模板

修改app/Resources/views/base.html.twig,增加如下代码:

    <div class="col-sm-8 col-xs-10"><h1><a href="{{ path('homepage') }}">lcsays</a></h1></div>
    <div class="col-sm-3 col-xs-1">
        <form action="{{ path('blog_search') }}">
            <input type="search" name="q" placeholder="搜文章" maxlength="200">
        </form>
    </div>

这其实就是在网页顶部增加了一个搜索框,这里面的input输入框的name设置成q,刚好对应了上面的$request->get('q');

搜索结果页

为了简单,我们尽量复用博客列表页,拷贝app/Resources/views/blog/list.html.twig到app/Resources/views/blog/search.html.twig,把

{% block title %}{{ subject.name }} - lcsays - 关注大数据技术{% endblock title %}

改成

{% block title %}{{ query }}的搜索结果 - lcsays - 关注大数据技术{% endblock title %}