需求
- 博客改版后一直没有增加搜索页(¬_¬没时间)
- 初步设想在标题/分类/标签/内容(太泛暂时舍弃)
- 搜索均为模糊搜索 比如关键词为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 %}