鍍金池/ 教程/ HTML/ 番外篇之——使用 _id 查詢
第9章 增加標(biāo)簽和標(biāo)簽頁(yè)面
番外篇之——使用 Mongoose
番外篇之——使用 Async
第4章 實(shí)現(xiàn)用戶頁(yè)面和文章頁(yè)面
第12章 增加友情鏈接
第14章 增加頭像
第7章 實(shí)現(xiàn)分頁(yè)功能
第5章 增加編輯與刪除功能
第11章 增加文章檢索功能
第3章 增加文件上傳功能
番外篇之——部署到 Heroku
第2章 使用 Markdown
第13章 增加404頁(yè)面
第16章 增加日志功能
第1章 一個(gè)簡(jiǎn)單的博客
番外篇之——使用 Handlebars
第10章 增加pv統(tǒng)計(jì)和留言統(tǒng)計(jì)
番外篇之——使用 Passport
第15章 增加轉(zhuǎn)載功能和轉(zhuǎn)載統(tǒng)計(jì)
第8章 增加存檔頁(yè)面
番外篇之——使用 generic pool
番外篇之——使用 _id 查詢
番外篇之——使用 Disqus
番外篇之——使用 KindEditor
第6章 實(shí)現(xiàn)留言功能

番外篇之——使用 _id 查詢

我們知道,MongoDB 會(huì)自動(dòng)為每個(gè)文檔添加一個(gè)特殊的 _id 鍵,這個(gè) _id 鍵的值是經(jīng)過特殊計(jì)算的長(zhǎng)度為 24 的字符串的 ObjectId 對(duì)象(詳見《MongoDB 權(quán)威指南》),因此保證了每個(gè)文檔的 _id 都是獨(dú)一無二的。那我們可不可以使用 _id 鍵查詢一個(gè)獨(dú)一無二的文檔呢?當(dāng)然可以,這也是設(shè)計(jì) _id 的原因所在。

注意:使用 name 、day 、title 查詢一篇文章有個(gè)小 bug ,即不能在同一天發(fā)表相同標(biāo)題的文章,或者說發(fā)表了相同標(biāo)題的文章后只能返回最近發(fā)表的那篇文章。使用 _id 就可以很好的避免這個(gè) bug 。

下面我們舉例使用 _id 代替使用 name 、day 、title 來查詢一篇文章,即將:

app.get('/u/:name/:day/:title')

修改為以下形式:

app.get('/p/:_id')

打開 post.js ,在最上面添加:

var ObjectID = require('mongodb').ObjectID;

將:

Post.getOne = function(name, day, title, callback) {

修改為:

Post.getOne = function(_id, callback) {

并將 Post.getOne() 內(nèi)兩處的:

"name": name,
"time.day": day,
"title": title

都修改為:

"_id": new ObjectID(_id)

打開 index.js ,將 app.get('/u/:name/:day/:title') 修改如下:

app.get('/p/:_id', function (req, res) {
  Post.getOne(req.params._id, function (err, post) {
    if (err) {
      req.flash('error', err); 
      return res.redirect('/');
    }
    res.render('article', {
      title: post.title,
      post: post,
      user: req.session.user,
      success: req.flash('success').toString(),
      error: req.flash('error').toString()
    });
  });
});

注意:我們將文章頁(yè)面的路由修改為 app.get('/p/:_id') 而不是 app.get('/u/:_id') 是為了防止和上面的用戶頁(yè)面的路由 app.get('/u/:name') 沖突,況且,p 也代表 post ,表示發(fā)表的文章的意思。

打開 index.ejs ,將:

<p><h2><a href="/u/<%= post.name %>/<%= post.time.day %>/<%= post.title %>"><%= post.title %></a></h2>

修改為:

<p><h2><a href="/p/<%= post._id %>"><%= post.title %></a></h2>

現(xiàn)在,運(yùn)行你的博客并發(fā)表一篇文章,從主頁(yè)點(diǎn)擊標(biāo)題進(jìn)入該文章頁(yè)面,就變成了以下的 url 形式:

http://localhost:3000/p/52553dcd5bb408ec11000002

注意:MongoDB 數(shù)據(jù)庫(kù)中是以以下形式存儲(chǔ) _id 的:

"_id" : ObjectId("52553dcd5bb408ec11000002")

我們可以直接使用 post._id 從數(shù)據(jù)庫(kù)中獲取 _id 的值(24 位長(zhǎng)字符串),但在查詢的時(shí)候,要把 _id 字符串包裝成 MongoDB 特有的 ObjectId 類型。

讀者可依此類推,自行將剩余的工作完成。