佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > mongoDB使用投影剔除‘額外’字段的操作過程

mongoDB使用投影剔除‘額外’字段的操作過程

熱門標(biāo)簽:服務(wù)外包 AI電銷 鐵路電話系統(tǒng) 百度競價排名 Linux服務(wù)器 地方門戶網(wǎng)站 呼叫中心市場需求 網(wǎng)站排名優(yōu)化

簡介

實(shí)際開發(fā)過程中,為便于開發(fā)人員定位問題,常存在多個額外的字段。例如:增加createdAt、updatedAt字段以查看數(shù)據(jù)的創(chuàng)建和更改時間。而對于客戶端而言,無需知道其存在。針對以上情況,本文詳細(xì)介紹了“額外”字段的用途以及處理過程。

技術(shù)棧

  • mongodb 4.0.20
  • mongoose 5.10.7

1  "額外"字段是什么

1.1 "額外"是指與業(yè)務(wù)無關(guān)

mongodb中,collection中存儲的字段并不僅僅有業(yè)務(wù)字段。有些情況下,會存儲多余的字段,以便于開發(fā)人員定位問題、擴(kuò)展集合等。

額外的含義是指 和業(yè)務(wù)無關(guān)、和開發(fā)相關(guān)的字段。這些字段不需要被用戶所了解,但是在開發(fā)過程中是至關(guān)重要的。

1.2 產(chǎn)生原因

產(chǎn)生額外字段的原因是多種多樣的。

  • 如使用mongoose插件向db中插入數(shù)據(jù)時,會默認(rèn)的生成_id、__v字段
  • 如軟刪除,則是通過控制is_deleted實(shí)現(xiàn)..

2 額外字段的分類

額外字段的產(chǎn)生原因有很多,可以以此進(jìn)行分類。

2.1 _id、__v字段

產(chǎn)生原因:以mongoose為例,通過schema->model->entity向mongodb中插入數(shù)據(jù)時,該數(shù)據(jù)會默認(rèn)的增加_id、__v字段。

_id字段是由mongodb默認(rèn)生成的,用于文檔的唯一索引。類型是ObjectID。mongoDB文檔定義如下:


MongoDB creates a unique index on the _id field during the creation of a collection. The _id index prevents clients from inserting two documents with the same value for the _id field. You cannot drop this index on the _id field.

__v字段是由mongoose首次創(chuàng)建時默認(rèn)生成,表示該條doc的內(nèi)部版本號。


The versionKey is a property set on each document when first created by Mongoose. This keys value contains the internal revision of the document. The versionKey option is a string that represents the path to use for versioning. The default is __v.

2.2 createdAt、updatedAt字段

createdAt、updatedAt字段是通過timestamp選項(xiàng)指定的,類型為Date。


The timestamps option tells mongoose to assign createdAt and updatedAt fields to your schema. The type assigned is Date.By default, the names of the fields are createdAt and updatedAt. Customize the field names by setting timestamps.createdAt and timestamps.updatedAt.

2.3 is_deleted字段

is_deleted字段是實(shí)現(xiàn)軟刪除一種常用的方式。在實(shí)際業(yè)務(wù)中,出于各種原因(如刪除后用戶要求再次恢復(fù)等),往往采用的軟刪除,而非物理刪除。

因此,is_deleted字段保存當(dāng)前doc的狀態(tài)。is_deleted字段為true時,表示當(dāng)前記錄有效。is_deleted字段為false時,表示當(dāng)前記錄已被刪除。

3 額外字段相關(guān)操作

3.1 額外字段生成

_id字段是必選項(xiàng);__v、createdAt、updatedAt字段是可配置的;status字段直接加在s對應(yīng)的chema中。相關(guān)的schema代碼如下:

isdeleted: {
 type: String,
 default:true,
 enum: [true, false],
},
id: {
 type: String,
 index: true,
 unqiue: true,
 default:uuid.v4(),
}},
{timestamps:{createdAt:'docCreatedAt',updatedAt:"docUpdatedAt"},versionKey:false});

通過配置schema中的timestamps選項(xiàng),可以將createdAt和updatedAt字段加入到doc中。在創(chuàng)建和更新doc時,這兩個字段無需傳入,就會自動變化。

3.2 額外字段清理

通過3.1可以明確的產(chǎn)生若干額外字段,但是客戶端調(diào)用接口并返回時,這些字段是無需得知的。因此需對額外字段進(jìn)行清理。清理方式分為投影和過濾。

以query、update接口為例。其中query接口用于:1、查詢指定字段 2、查詢?nèi)孔侄?3、分頁排序查詢。update接口用于更新并返回更新后的數(shù)據(jù)。

根據(jù)是否需要指定字段、和collection中有無內(nèi)嵌的情況劃分,一共有4類。接著針對這4種情況進(jìn)行分析。

1、有指定字段、無內(nèi)嵌

2、無指定字段、無內(nèi)嵌

3、有指定字段、有內(nèi)嵌

4、無指定字段、有內(nèi)嵌

3.2.1 投影

有指定字段是指在查詢時指定查詢字段,而無需全部返回。mongo中實(shí)現(xiàn)指定的方式是投影 (project) 。mongo官方文檔中定義如下:


The $project takes a document that can specify the inclusion of fields, the suppression of the _id field, the addition of new fields, and the resetting of the values of existing fields. Alternatively, you may specify the exclusion of fields.

$project可以做3件事:

1.指定包含的字段、禁止_id字段、添加新字段

2.重置已存在字段的值

3.指定排除的字段

我們只需關(guān)注事情1、事情3。接著查看mongoose中對project的說明:


When using string syntax, prefixing a path with - will flag that path as excluded. When a path does not have the - prefix, it is included. Lastly, if a path is prefixed with +, it forces inclusion of the path, which is useful for paths excluded at the schema level.

A projection must be either inclusive or exclusive. In other words, you must either list the fields to include (which excludes all others), or list the fields to exclude (which implies all other fields are included). The _id field is the only exception because MongoDB includes it by default.

注意:此處指query "projection"

mongoose表明:投影要么是全包含,要么是全剔除。不允許包含和剔除同時存在。但由于

_id是MongoDB默認(rèn)包含的,因此_id是個例外。

select project投影語句組裝代碼:

 /**
 * 添加通用篩選條件
 * @param {*} stat 已裝配的篩選語句 
 * @param {*} collection collectionName
 * @return {*} 組裝完成的語句
 */
 function addCommonSelectCond(stat,collection)
 {
 if(typeof(stat)!="object") return;

 stat["_id"] = 0;
 stat["__v"] = 0;
 stat["status"] = 0;
 stat["docCreatedAt"] = 0;
 stat["docUpdatedAt"] = 0;

 var embeddedRes = hasEmbedded(collection);
 if(embeddedRes["isEmbedded"])
 {
 for(var item of embeddedRes["embeddedSchema"])
 {
 stat[item+"._id"] = 0;
 stat[item+".__v"] = 0;
 stat[item+".status"] = 0;
 stat[item+".docCreatedAt"] = 0; 
 stat[item+".docUpdatedAt"] = 0; 
 }
 }
 return stat;
 }

3.2.2 過濾

通過findOneAndupdate、insert、query等返回的doc對象中(已經(jīng)過lean或者toObject處理),是數(shù)據(jù)庫中真實(shí)狀態(tài)。因此需要對產(chǎn)生的doc進(jìn)行過濾,包括doc過濾和內(nèi)嵌文檔過濾。

/**
 * 處理自身及內(nèi)嵌的表
 * @param {*} collection 查詢的表
 * @param {*} doc 已查詢出的結(jié)果
 * @returns doc 清理后的結(jié)果
 */
static clearDoc(collection,doc){
 if(doc === undefined || doc === null || typeof doc != "object" ) return null;
 doc = this.clearExtraField(doc);

 var res = hasEmbedded(collection);
 if(res["isEmbedded"])
 {
 let arr = res["embeddedSchema"];
 for(var item of arr){
 if(doc[item])
 doc[item] = this.clearArray(doc[item]);
 }
 }
 return doc;
}

static clearExtraField(doc){
 if(doc === null || typeof doc != "object")
 return;
 
 var del = delete doc["docCreatedAt"]
 delete doc["docUpdatedAt"]
 delete doc["_id"]
 delete doc["__v"]
 delete doc["status"];
 if(!del) return new Error("刪除額外字段出錯");

 return doc;
}

static clearArray(arr)
{
 if(!Array.isArray(arr)) return;

 var clearRes = new Array();
 for(var item of arr){
 clearRes.push(this.clearExtraField(item));
 }
 return clearRes;
}

細(xì)心的讀者已經(jīng)發(fā)現(xiàn)了,投影和過濾的字段內(nèi)容都是額外字段。那什么情況下使用投影,什么情況下使用過濾呢?

關(guān)于這個問題,筆者的建議是如果不能確保額外字段被剔除掉,那就采取雙重認(rèn)證:查詢前使用投影,查詢后使用過濾。

4 總結(jié)

本文介紹了實(shí)際業(yè)務(wù)中往往會產(chǎn)生額外字段。而在mongoDB中,"消除"額外字段的手段主要是投影、過濾。

以使用頻率最高的查詢接口為例,整理如下:

指定選項(xiàng) 內(nèi)嵌選項(xiàng) 查詢前投影 查詢后過濾
有指定 無內(nèi)嵌 ×
有指定 有內(nèi)嵌 ×
無指定 無內(nèi)嵌 ×
無指定 有內(nèi)嵌 ×

因此,筆者建議無論schema中是否配置了options,在查詢時組裝投影語句,查詢后進(jìn)行結(jié)果過濾。這樣保證萬無一失,

額外字段才不會漏到客戶端**。

到此這篇關(guān)于mongoDB使用投影剔除‘額外'字段的文章就介紹到這了,更多相關(guān)mongoDB用投影剔除額外字段內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

標(biāo)簽:仙桃 衡水 湖南 黃山 銅川 湘潭 崇左 蘭州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《mongoDB使用投影剔除‘額外’字段的操作過程》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    崇阳县| 潜山县| 奈曼旗| 黄石市| 汕头市| 开封县| 兰溪市| 通江县| 信阳市| 肇东市| 乌恰县| 东兰县| 萨嘎县| 瑞昌市| 佛学| 邵阳县| 大英县| 靖远县| 泰安市| 砚山县| 民丰县| 平潭县| 安福县| 龙岩市| 靖安县| 阜阳市| 寻乌县| 嘉祥县| 东海县| 五原县| 广安市| 西华县| 高邑县| 鲁山县| 邢台县| 北碚区| 武强县| 芦山县| 城步| 廊坊市| 乌鲁木齐市|