-
Notifications
You must be signed in to change notification settings - Fork 1
Step6
上一步:Step5. 支持图片元数据更新
本步骤完整源码在 workflow/step-6 分支上,提交记录为
8f7018e
如果用户上传的文件很多,那么列出全部数据将会耗费大量的时间和资源。这种情况下,我们一般会提供分页接口来支持数据分页。同时,客户端已经具有为图片添加元数据(作者、标签、Alt文本)的能力,所以客户端也希望可以通过搜索来列出相关的图片。
分页接口设计里面,一般包含 pageIndex
表示请求的页面以及 pageSize
表示请求每页的数据量。在本例,我们直接使用用户从 QueryString
传过来的这两个参数。其中 pageIndex
从 0 开始索引。
分页接口的设计里面,还要求返回给客户端总记录数,这个数据将用户客户端计算最大页码。下面,我们修改 handle/list.js
的代码,添加分页支持。
// handle/list.js
const params = request.query;
// ...connected to db
const imageCollection = db.collection("images");
const total = yield imageCollection.count();
let query = imageCollection.find();
let pageIndex = +params.pageIndex;
let pageSize = +params.pageSize;
// see if user has request for a paging
if (!isNaN(pageIndex) && !isNaN(pageSize)) {
pageIndex = pageIndex || 0;
pageSize = pageSize || 10;
const start = pageIndex * pageSize;
query = query.skip(start).limit(pageSize);
}
const list = yield query.toArray();
print({
total,
list,
paging: { pageIndex, pageSize }
});
(只列出了关键代码,完整修改请参考 8f7018e
)
这里关键代码是 query = query.skip(start).limit(pageSize)
,这里的意思是跳过游标的 start
条记录,尝试取 pageSize
条记录。
同时,在输出分页列表的同时,也计算了集合里面的总记录数(使用 .count()
方法)并输出。
现在,用户可以在 URL 上指定 pageIndex
和 pageSize
进行分页了。在这个基础上,我们添加搜索功能。
那么,搜索应该是在分页之前还是之后呢?思考过后,发现只能在分页之前进行。否则,不能保证分页是基于搜索之后的结果的。
同时,我们统计记录总数的时候,也需要根据搜索的条件进行统计,否则就会出现「这个关键字明明有 100 条记录,怎么到了第 2 页就没数据了」这样的情形。
// handle/list.js
// ...connected to db
const imageCollection = db.collection("images");
let criteria = {};
// build search criteria
const keyword = params.search;
if (keyword) {
const search = new RegExp(keyword);
console.log("search: " + keyword);
criteria.$or = ['name', 'meta.author', 'meta.labels', 'meta.alt'].map(field => ({ [field]: search }));
}
const total = yield imageCollection.count(criteria);
let query = imageCollection.find(criteria);
(只列出了关键代码,完整修改请参考 8f7018e
)
进行搜索的时候,我们会创建 MongoDB Query(代码中的 criteria
),然后传入 find()
方法中。
上面构造了一个「或」类型的搜索,就是希望在指定的字段上匹配到了关键字,都认为记录匹配。
现在,可以试试用 Postman 测试,搜索一下作者、标签或者 Alt 文本。
下一步:Step7. 添加搜索历史记录