国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Mongoose中document和object的區(qū)別

zone / 1752人閱讀

摘要:愿意是因?yàn)樵俅畏祷氐氖菍儆诘膶?shí)例,而不是一個(gè)普通的對(duì)象?,F(xiàn)在我們就看一看這二者的區(qū)別。至此,這個(gè)問(wèn)題引起的一系列的探究也是告一段落了。其實(shí)還有另外一些奇怪的地方,被人所詬病,在此也不一一細(xì)數(shù)了。

這個(gè)問(wèn)題其實(shí)是mongoose非常常見(jiàn)的問(wèn)題,經(jīng)常有很多以前沒(méi)遇到這個(gè)問(wèn)題的人都會(huì)被這個(gè)問(wèn)題弄得懷疑人生。我們先介紹一些問(wèn)題的背景。先看下面一段代碼:

router.get("/", function(req, res, next) {
  // res.render("index", { title: "Express" });
  const model = mongoose.model("realestate");
  const queryCretia = {};
  model.find(queryCretia, (err, docs) => {
    res.render("index", {
      title: "express",
      docs: docs
    })
  })
});


  
    <%= title %>
    
  
  
    

<%= title %>

Welcome to <%= title %>

    <% docs.forEach(function(doc){ %>
  • <%= doc.type %>
  • <% }) %>

在第一段代碼中,通過(guò)model.find我們應(yīng)該能夠獲取到根據(jù)queryCriteria獲取的結(jié)果,結(jié)果應(yīng)該是一個(gè)對(duì)象數(shù)組,類似于這樣:

[{
    "_id" : ObjectId("59bdeadb2a5c612514ee7970"),
    "title" : "好樓層,中等裝修,滿5年,上門(mén)實(shí)拍",
    "type" : "2室1廳",
    "square" : "75.42平",
    "direction" : "朝南",
    "floor" : "中區(qū)/6層",
    "unitPrice" : 47732,
    "totalPrice" : 360,
    "location" : null,
    "specialExplain" : "滿五",
    "url" : "http://sh.lianjia.com//ershoufang/sh4528035.html",
    "station" : "江楊北路",
    "line" : "3號(hào)線",
    "updateTime" : "2017-09-17 11:24:11"
}
{
    "_id" : ObjectId("59bdeadb2a5c612514ee7971"),
    "title" : "南北戶型,廚衛(wèi)全明,高區(qū)采光好,裝修精美",
    "type" : "2室2廳",
    "square" : "90.92平",
    "direction" : "朝南北",
    "floor" : "高區(qū)/6層",
    "unitPrice" : 46194,
    "totalPrice" : 420,
    "location" : null,
    "specialExplain" : "滿五",
    "url" : "http://sh.lianjia.com//ershoufang/sh4546221.html",
    "station" : "江楊北路",
    "line" : "3號(hào)線",
    "updateTime" : "2017-09-17 11:24:11"
}]

預(yù)期index.ejs應(yīng)該渲染的頁(yè)面是一個(gè)ul渲染的結(jié)果,類似于

2室1廳

2室2廳

當(dāng)然,理想很豐滿,現(xiàn)實(shí)很骨感。我就是死活渲染不出來(lái)doc.type。照理說(shuō)應(yīng)該是不可能的,在index.ejsdoc就是一個(gè)對(duì)象,我為什么不能獲取doctype屬性呢?這不合理,太不合理了!

老實(shí)說(shuō),這個(gè)問(wèn)題我之間也是遇到過(guò),當(dāng)初我是想修改這個(gè)doc的屬性,但是死活沒(méi)有辦法修改,當(dāng)初也是花了很久找到原因。這次我就把這個(gè)問(wèn)題好好地研究一下。

先說(shuō)結(jié)果,以及解決方法把。我比較喜歡劇透。愿意是因?yàn)樵俅畏祷氐?b>doc是屬于Document的實(shí)例,而不是一個(gè)普通的對(duì)象。也就是說(shuō)它和普通的對(duì)象是不一樣的,它沒(méi)有普通對(duì)象的一些方法,普通對(duì)象也沒(méi)有它身上的一些方法。解決方案有幾種,不過(guò)究其根本都是將這種document轉(zhuǎn)化為普通的對(duì)象:

方法1:

利用toObject方法

docs.forEach(doc => {
    return doc.toObject();
})
方法2:

利用JSON方法,這是我想到的一個(gè)方法,具體深層原因在這就不展開(kāi)了:

docs = JSON.stringify(docs);
docs = JSON.parse(docs);
方法3:

利用lean方法:

model.find().lean().exec((err, docs) => {
....
})

上述的三種方法應(yīng)該都能成功將find獲取的結(jié)果轉(zhuǎn)化為普通的對(duì)象。

但是我還想知道到底document和一個(gè)普通的對(duì)象到底有什么區(qū)別,區(qū)別在哪里呢?

我們假設(shè)find獲取的結(jié)果是docs,轉(zhuǎn)化為普通對(duì)象的結(jié)果是docs1。現(xiàn)在我們就看一看這二者的區(qū)別。理論上docsdocs1都應(yīng)該是數(shù)組,而它們中元素都應(yīng)該是一個(gè)對(duì)象,我們先來(lái)看看是不是這樣呢?

console.log(Object.prototype.toString.call(docs));
consoele.log(Object.prototype.toString.call(docs[0]));

console.log(Object.prototype.toString.call(docs1));
console.log(Object.prototype.toString.call(docs1[0]))

我們通過(guò)上述方法可以獲取docs以及docs1的類型以及其中元素的類型,結(jié)果是:

[object Array]
[object Object]

[object Array]
[object Object]

和我們預(yù)想中的一模一樣,那問(wèn)題不在這,那我們就探究探究docs[0]以及docs1[0]的原型把,看看它的原型到底是什么呢?知道JS的人,應(yīng)該都知道JS中的原型鏈。在此,我們就通過(guò)__proto__來(lái)粗暴地獲取對(duì)象的原型:

console.dir(doc[0].__proto__);

console.dir(docs[0].__proto__);

結(jié)果是:

model {
  db:
   NativeConnection {
     base:
      Mongoose {
        connections: [Array],
        models: [Object],
        modelSchemas: [Object],
        options: [Object],
        plugins: [Array] },
     collections: { realestates: [Object] },
     models: { realestate: [Object] },
     config: { autoIndex: true },
     replica: false,
     hosts: null,
     host: "127.0.0.1",
     port: 27017,
     user: undefined,
     pass: undefined,
     name: "real_estate_info",
     options:
      { db: [Object],
        auth: {},
        server: [Object],
        replset: [Object],
        mongos: undefined },
     otherDbs: [],
     _readyState: 1,
     _closeCalled: false,
     _hasOpened: true,
     _listening: false,
     db:
      Db {
        domain: null,
        _events: [Object],
        _eventsCount: 6,
        _maxListeners: undefined,
        s: [Object],
        serverConfig: [Getter],
        bufferMaxEntries: [Getter],
        databaseName: [Getter],
        _listening: true },
     _events:
      { connected: [Function],
        error: [Function: bound bound consoleCall],
        disconnected: [Function: bound bound consoleCall],
        reconnected: [Function: bound bound consoleCall] },
     _eventsCount: 4 },
  discriminators: undefined,
  id: [Getter/Setter],
  __v: [Getter/Setter],
  _id: [Getter/Setter],
  schema:
   Schema {
     obj: undefined,
     paths: { _id: [Object], __v: [Object] },
     aliases: {},
     subpaths: {},
     virtuals: { id: [Object] },
     singleNestedPaths: {},
     nested: {},
     inherits: {},
     callQueue: [ [Array], [Array], [Array], [Array], [Array], [Array] ],
     _indexes: [],
     methods: {},
     statics: {},
     tree: { _id: [Object], __v: [Function: Number], id: [Object] },
     query: {},
     childSchemas: [],
     plugins: [ [Object], [Object], [Object], [Object] ],
     s: { hooks: [Object], kareemHooks: [Object] },
     options:
      { retainKeyOrder: false,
        typeKey: "type",
        id: true,
        noVirtualId: false,
        _id: true,
        noId: false,
        validateBeforeSave: true,
        read: null,
        shardKey: null,
        autoIndex: null,
        minimize: true,
        discriminatorKey: "__t",
        versionKey: "__v",
        capped: false,
        bufferCommands: true,
        strict: true,
        pluralization: true },
     "$globalPluginsApplied": true,
     _requiredpaths: [] },
  collection:
   NativeCollection {
     collection: Collection { s: [Object] },
     opts: { bufferCommands: true, capped: false },
     name: "realestates",
     collectionName: "realestates",
     conn:
      NativeConnection {
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        hosts: null,
        host: "127.0.0.1",
        port: 27017,
        user: undefined,
        pass: undefined,
        name: "real_estate_info",
        options: [Object],
        otherDbs: [],
        _readyState: 1,
        _closeCalled: false,
        _hasOpened: true,
        _listening: false,
        db: [Object],
        _events: [Object],
        _eventsCount: 4 },
     queue: [],
     buffer: false,
     emitter:
      EventEmitter {
        domain: null,
        _events: {},
        _eventsCount: 0,
        _maxListeners: undefined } },
  "$__original_save": { [Function] numAsyncPres: 0 },
  save: { [Function: wrappedPointCut] "$originalFunction": "$__original_save", "$isWrapped": true },
  _pres:
   { "$__original_save": [ [Object], [Object], [Object] ],
     "$__original_remove": [ [Object] ] },
  _posts: { "$__original_save": [], "$__original_remove": [] },
  "$__original_remove": { [Function] numAsyncPres: 1 },
  remove:
   { [Function: wrappedPointCut]
     "$originalFunction": "$__original_remove",
     "$isWrapped": true },
  "$__original_validate": [Function],
  validate:
   { [Function: wrappedPointCut]
     "$originalFunction": "$__original_validate",
     "$isWrapped": true } }

以及

{}

很顯然,問(wèn)題就是在這里,docs[0]docs[0]的原型并不是一個(gè)東西。而js中對(duì)象通過(guò).或者是[]訪問(wèn)屬性都是調(diào)用了Object中的某個(gè)方法,但具體什么方法我不太記得。然而docs中的原型或者其原型的原型也是沒(méi)有這個(gè)方法的,因此他就沒(méi)辦法去訪問(wèn)這個(gè)屬性。

其實(shí)docs[0].__proto__.__proto__是Model,docs[0].__proto__.__proto__.__proto__是Document,docs[0].__proto__.__proto__.__proto__.__proto__才是{}。

至此,這個(gè)問(wèn)題引起的一系列的探究也是告一段落了。其實(shí)Mongoose還有另外一些奇怪的地方,被人所詬病,在此也不一一細(xì)數(shù)了。從問(wèn)題的發(fā)現(xiàn),到寫(xiě)這篇文章大概花了大半天的時(shí)間,以前遇到問(wèn)題就找到解決辦法就停止了,但是這一次通過(guò)這樣深入地去發(fā)現(xiàn),可能就會(huì)發(fā)掘到更多的東西。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/91870.html

相關(guān)文章

  • Mongoose 之 Population 使用

    摘要:使用可以實(shí)現(xiàn)在一個(gè)中填充其他的。表示關(guān)聯(lián)注意被關(guān)聯(lián)的的必須是和才有效。類型的時(shí),格式如為表示不填充,為時(shí)表示填充。以鍵值對(duì)的形式表示?;卣{(diào)函數(shù),接收兩個(gè)參數(shù),錯(cuò)誤和填充完的。參考數(shù)據(jù)庫(kù)的最簡(jiǎn)單實(shí)現(xiàn)使用之原文鏈接 Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。 什么是ODM? 其實(shí)和ORM(Object Relational Mapp...

    timger 評(píng)論0 收藏0
  • [轉(zhuǎn)]mongodbpopulate方法

    摘要:使用可以實(shí)現(xiàn)在一個(gè)中填充其他的。表示關(guān)聯(lián)注意被關(guān)聯(lián)的的必須是和才有效。封裝了很多查詢的方法,使得對(duì)數(shù)據(jù)庫(kù)的操作變得簡(jiǎn)單啦。這里分享一下方法用法。類型的時(shí),格式如為表示不填充,為時(shí)表示填充。類型,可選,指定附加的查詢條件。 Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。 什么是ODM? 其實(shí)和ORM(Object Relational...

    ranwu 評(píng)論0 收藏0
  • (轉(zhuǎn))Mongoose學(xué)習(xí)參考文檔

    摘要:轉(zhuǎn)自一快速通道名詞解釋一種以文件形式存儲(chǔ)的數(shù)據(jù)庫(kù)模型骨架,不具備數(shù)據(jù)庫(kù)的操作能力由發(fā)布生成的模型,具有抽象屬性和行為的數(shù)據(jù)庫(kù)操作對(duì)由創(chuàng)建的實(shí)體,他的操作也會(huì)影響數(shù)據(jù)庫(kù)注意本學(xué)習(xí)文檔采用嚴(yán)格命名方式來(lái)區(qū)別不同對(duì)象,例如的文本屬性的數(shù)據(jù)庫(kù)模型實(shí) 轉(zhuǎn)自 https://cnodejs.org/topic/504... 一、快速通道 1.1 名詞解釋 Schema : 一種以文件形式存儲(chǔ)的...

    Sleepy 評(píng)論0 收藏0
  • Mongoose簡(jiǎn)要API

    摘要:是在環(huán)境下對(duì)進(jìn)行便捷操作的對(duì)象模型工具因此,要使用,則必須安裝環(huán)境以及數(shù)據(jù)庫(kù)。使操作更簡(jiǎn)單便捷。找到記錄,并且將遞增,返回后的為之前的。這個(gè)屬性很有用,對(duì)數(shù)字直接進(jìn)行增減。,要返回的字段與的第二個(gè)參數(shù)一致。 Mongoose是在node.js環(huán)境下對(duì)mongodb進(jìn)行便捷操作的對(duì)象模型工具 因此,要使用mongoose,則必須安裝node.js環(huán)境以及mongodb數(shù)據(jù)庫(kù)。mongoo...

    王巖威 評(píng)論0 收藏0
  • mongoose學(xué)習(xí)筆記(超詳細(xì))

    摘要:返回的是轉(zhuǎn)換為字符串后的值。默認(rèn)行為禁止在一個(gè)中如果沒(méi)有定義域,那么將會(huì)默認(rèn)分配一個(gè)域。通過(guò)在中設(shè)置這個(gè)字段可以阻止生成獲得。我們也能設(shè)置其它的安全等級(jí)如表示如果秒內(nèi)寫(xiě)操作沒(méi)有完成,將會(huì)超時(shí)。在,和方法只檢查頂級(jí)的的選項(xiàng)設(shè)置。 原文出處 名詞解釋 Schema: 一種以文件形式存儲(chǔ)的數(shù)據(jù)庫(kù)模型骨架,不具備數(shù)據(jù)庫(kù)的操作能力 Model: 由Schema編譯而成的假想(fancy)構(gòu)造器...

    Bowman_han 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<