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

in ThinkJS笔记 with 0 comments, 6997 views

需求

关键点

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 %}
Responses ${replyToWho} / Cancel Reply