当我坐在那架破旧古钢琴旁边的时候,我对 最幸福的国王也不羡慕。—— 海顿

thinkjs学习笔记--给博客增加模糊搜索功能

需求

  • 博客改版后一直没有增加搜索页(¬_¬没时间)
  • 初步设想在标题/分类/标签/内容(太泛暂时舍弃)
  • 搜索均为模糊搜索 比如关键词为prefix可以搜索到标签"prefixfree-js"
  • 和其它列表页一样需要分页[参考thinkjs分页]

关键点

model.mongo查询条件(OR)

由上述需求点可以看出我们最后需要的是一个查询的合集,即在标题/分类/标签三者之中任意一个条件满足均可。想象大致查询语句为{$or:[条件1,条件2,条件3...]}

利用正则进行模糊查询

正则用来模糊查询再适合不过了,而且mongo也支持.

router路由设置

得益于thinkjs的灵活路由机制,这里我们使用自定义路由来达到想要的效果.

[/^search\/(\w+)\/page\/(\d+)$/, "home/article/search?keyword=:1&page=:2"],

核心代码

controler增加searchAction

async searchAction(){
    let query,aOR=[];
    let keyword = this.get('keyword');
    let pageFor = "/search/" + keyword + '/';
    let cateModel = this.model("cate");
    let userModel = this.model("user");
    let model = this.model("article");
    let currentPage = this.get("page")||1;
    let pagesize = this.get("pagesize")||10;
    let cateId,tagList;
    let reTitle =new RegExp(".*" + keyword + ".*",'i');
        cateId = await cateModel.getCateIDbyName(keyword);
    let tagModel = this.model("tag");
        tagList = await tagModel.getTagList();
      // 如果没有则执行模糊查询title,tagName,cateId是否包含关键字
      // 如果查询无结果则显示为空
      if(cateId){
          aOR.push({'cateId':''+ cateId});
      }

      if(!think.isEmpty(tagList)) {
          let _index = tagList.findIndex(item => {
              if(item.tagName.search(keyword)!=-1){
                  return item.tagName;
              }
          });
          if(~_index){
              let reTitle =new RegExp(".*" + keyword + ".*",'i');
              aOR.push({'tagName':''+ tagList[_index].tagName});
          }
      }

      aOR.push({'title':reTitle});

      query = {$or:aOR,"status": 1};

    // status 1只返回已发布的文章
    let list = await model.where(query).order("date DESC").page(currentPage,pagesize).countSelect();


    for (var i = 0; i < list.length; i++) {
        let authorId = list[i].authorId;
        list[i].author_name = await userModel.getNickName(authorId);
    }
      let pageData = this.pagination(list);
      this.assign({
          "pageType":'search',
          count:list.count,
          keyword:keyword,
          "list":list,
          "title":"搜索:\""+ (keyword || '全部')  + "\"",
          pageData:pageData,
          "pageFor":pageFor
      });
      return this.displayView('list');
  }

总结

上述代码可能有些不完整,毕竟项目环境不通,不过大致思路是一样的,在些记录一下,加深印象。如果能够帮到他人那自然更好!

最后有个小细节,当在搜索框输入关键字查找时,跳转到搜索结果页时我们需要把关键字记住,这样会有更好的体验,仅需在模板上做些变量定义及判断处理即可。

<!--记忆搜索关键字-->
<li class="search-item">
    <form action="/search"><input id="js_searchIpt" type="text" name="keyword" value="{{keyword or ''}}" placeholder="今天想学点什么?" autocomplete="off"><button class="btn-search"><svg class="ico ico-search"><use xlink:href="#ico-search"></use></svg></button></form>
</li>
<!--如果搜索页记录为空-->
{% if pageType == 'search' and count == 0 %}
    <div class="search-empty">很抱歉,没有查询到<strong>"{{keyword}}"</strong>的相关内容</div>
{% endif %}

分享

分享本文章

文章来源
182410

2017-01-08

标签

thinkjs

right left pencil2 css3 node design eye tags search rss back user pacman film