2017-06-04 6 views
-1

クエリが_idまたはpermalinkと一致するドキュメントベースから「ページ」をフェッチする方法を作成しようとしています。明らかに、クエリはケースが「こんにちは世界」や他の文字列パーマリンクである場合のObjectIdではありません、今

'Cast to ObjectId failed for value "hello-world" at path "_id" for model "pages"'

次のコード例は、マングースのエラーを返します。では、どうすれば$を使うか、この場合はどうやって行くのですか、それとももっとスマートな方法がありますか?

/** 
* Describes methods to create, retrieve, update, and delete pages 
* @returns void 
*/ 
function Pages() { 
    this.pages = require('../models/pages') 
    this.users = require('../models/users') 
    require('mongoose').connect(require('../../config/database/mongodb').url) 
} 

/** 
* Retrieve a page by permalink or id 
* @param {string} pageQuery - id or permalink 
* @callback {function} cFunction 
*/ 
Pages.prototype.getOne = function(pageQuery, cFunction) { 
    this.pages.findOne({$or: [{ 'permalink': pageQuery }, { '_id': pageQuery }] }) 
    .populate('author', 'email') 
    .select('title permalink body author') 
    .exec(function(error, result) { 
     if (error) { 
      cFunction(error) 
      return 
     } 
     cFunction(result) 
    }) 
} 

ページのモデル

const mongoose = require('mongoose'), 
    Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId, 
    pages = new Schema({ 
     title: { type: String }, 
     permalink: { type: String, unique: true }, 
     body: { type: String }, 
     author: { type: ObjectId, ref: 'users' }, 
     createdAt: { type: Date }, 
     revisedAt: { type: Date } 
    }) 
    .index({ 
     title: 'text', 
     permalink: 'text', 
     body: 'text' 
    }) 
    module.exports = mongoose.model('pages', pages) 

ユーザーモデル

const mongoose = require('mongoose'), 
    Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId, 
    users = new Schema({ 
     email: { type: String, unique: true }, 
     username: { type: String, unique: true }, 
     password: { type: String }, 
     createdAt: { type: Date } 
    }) 
    .index({ 
     email: 'text', 
     username: 'text' 
    }) 
module.exports = mongoose.model('users', users) 
+0

それはpageQuery'は ''「こんにちは世界」である 'として渡された現在の値のように見えます。私はあなたが何かをデバッグしていて、どこかで変数宣言を削除するのを忘れたと思う。したがって、エラー。 –

+0

@ NeeLunn私は質問のページとユーザーの両方のモデルを追加しました。はい、私はテストで 'hello-world'をクエリしていますが、それは全体のポイントです。私はidまたはパーマリンクがクエリと一致するドキュメントベースからページを取得することができます。これはIDまたはパーマリンクにすることができます。 –

+0

ええ、私はあなたがこの文字列をこの関数への入力として明確に供給しているので、それを引っ込めました。 * "あなたのコードを検索してください、あなたはこれが本当であることを知っています" * –

答えて

1

あなたがnew ObjectId(pageQuery)を実行し、それが有効なのObjectIdはない場合、それはあなたを伝えるエラーがスローされますように見えますそれは(つまり:エラーが渡された引数は、12バイトの単一の文字列または24の16進数の文字列でなければなりませんracters)

Pages.prototype.getOneの先頭にあるtry/catchブロックを使用してpageQueryOid変数をキャストしてください。catchブロックに到達した場合は、pageQueryが有効ではないことがわかりますObjectId。

このメソッドを使用すると、$やフィルタは不要になりますが、pageQueryが有効なObjectIdであるかどうかに基づいて正確なフィルタを構築できます。以下では、これがどのように見えるかのほんの一例ですが、あなたはあなたのニーズを満たすためにそれを更新することができます

Pages.prototype.getOne = function(pageQuery, cFunction) { 
    var ObjectId = require('mongoose').Types.ObjectId 
    var pageQueryOid 
    try { 
     pageQueryOid = new ObjectId(pageQuery) 
    } catch(err) { 
     console.log("pageQuery is not a valid ObjectId...") 
    } 

    var filter 
    if (pageQueryOid) { 
     filter = { '_id': pageQueryOid } 
    } else { 
     filter = { 'permalink': pageQuery } 
    } 

    this.pages.findOne(filter) 
    .populate('author', 'email') 
    .select('title permalink body author') 
    .exec(function(error, result) { 
     if (error) { 
      cFunction(error) 
      return 
     } 
     cFunction(result) 
    }) 
} 
関連する問題