MongoDB權威指南第二版學習筆記(四)—增刪改文檔下

来源:http://www.cnblogs.com/ginb/archive/2016/12/18/6189456.html
-Advertisement-
Play Games

$slice 如果希望數組的最大長度是固定的,那麼可以將 $slice 和 $push 組合在一起使用,就可以保證數組不會超出設定好的最大長度。$slice 的值必須是負整數。 假設$slice的值為10,如果$push 後的數組的元素個數小於10,那麼所有元素都會保留。反之,只有最後那10個元素會 ...


$slice

如果希望數組的最大長度是固定的,那麼可以將 $slice 和 $push 組合在一起使用,就可以保證數組不會超出設定好的最大長度。$slice 的值必須是負整數。

假設$slice的值為10,如果$push 後的數組的元素個數小於10,那麼所有元素都會保留。反之,只有最後那10個元素會保留。因此,$slice 可以用來在文檔中創建一個隊列。

db.class.insert({"班級":"1班"})

WriteResult({ "nInserted" : 1 })
> db.class.update(
... {"班級":"1班"},
... {"$push":{"students":{
... "$each":["zs","ls","ww"],
... "$slice":-5}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.class.findOne()
{
        "_id" : ObjectId("5854b5a0e7d717fcb974637b"),
        "班級" : "1班",
        "students" : [
                "zs",
                "ls",
                "ww"
        ]
}

> db.class.update(
...  {"班級":"1班"},
...  {"$push":{"students":{
... "$each":["yyb","rhr","www","qqq","eee","rrr"],
... "$slice":-5}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.class.findOne()
{
        "_id" : ObjectId("5854b5a0e7d717fcb974637b"),
        "班級" : "1班",
        "students" : [
                "rhr",
                "www",
                "qqq",
                "eee",
                "rrr"
        ]
}
> 

也可以在清理元素之前使用$sort,只要向數組中添加子對象就需清理,先排序後保留指定的個數。

> db.class.update({},{ "班級" : "一班"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>  db.class.update(
...  {"班級":"一班"},
... {"$push":{"students":
...  {"$each":[{"name":"aaa","age":1},{"name":"bbb","age":2},{"name":"ccc","age":3}],
...  "$slice":-2,
...  "$sort":{"age":-1}}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.class.findOne()
{
        "_id" : ObjectId("5854b5a0e7d717fcb974637b"),
        "班級" : "一班",
        "students" : [
                {
                        "name" : "bbb",
                        "age" : 2
                },
                {
                        "name" : "aaa",
                        "age" : 1
                }
        ]
}
> 

$ne與$addToSet

如果想將數組作為數據集使用,保證數組內的元素不會重覆。可以在查詢文檔中用$ne或者$addToSet來實現。有些情況$ne根本行不通,有些時候更適合用$addToSet

> db.papers.insert({"authors cited":["yyb"]})
WriteResult({ "nInserted" : 1 })
> db.papers.update({"authors cited":{"$ne":"Richie"}}, {"$push":{"authors cited":"Richie"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.papers.findOne()
{
        "_id" : ObjectId("5854c900e7d717fcb974637e"),
        "authors cited" : [
                "yyb",
                "Richie"
        ]
}
> db.papers.update({"authors cited":{"$ne":"Richie"}}, {"$push":{"authors cited":"Richie"}})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> 
 db.user.findOne()
{
        "_id" : ObjectId("5854cb40e7d717fcb974637f"),
        "username" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}

> db.user.update(
... ... {"username":"joe"},
... ... {"$addToSet":{"emails":"[email protected]"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
>  db.user.update(
... ... ... {"username":"joe"},
... ... ... {"$addToSet":{"emails":"[email protected]"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.findOne()
{
        "_id" : ObjectId("5854cb40e7d717fcb974637f"),
        "username" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> 

$addToSet$each組合起來,可以添加多個不同的值。而用$ne$push組合就不能實現。

$addToSet與$push的區別:前者添加到數組中時會去重,後者不會。

>db.user.insert({ "username" : "joe"})
>  db.user.update(
... {"username" : "joe"},
... 
... {"$addToSet":
...  {"emails" :{"$each": [
... "[email protected]",
...  "[email protected]",
... "[email protected]",
... "[email protected]",
...  "[email protected]"]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.findOne()
{
        "_id" : ObjectId("5854ce5ce7d717fcb9746380"),
        "username" : "joe",
        "emails" : [
                "[email protected]",
                "[email protected]",
                "[email protected]",
                "[email protected]"
        ]
}
> 

從數組中刪除元素

$pop

可以從數組任何一端刪除元素。

{“$pop”:{“key”:1}}從數組末尾刪除一個元素

{“$pop”:{“key”:-1}}從數組頭部刪除一個元素

> db.class.findOne()
{
        "_id" : ObjectId("5854b5a0e7d717fcb974637b"),
        "班級" : "一班",
        "students" : [
                {
                        "name" : "bbb",
                        "age" : 2
                },
                {
                        "name" : "aaa",
                        "age" : 1
                }
        ]
}
> db.class.update(
... {"班級" : "一班"},
... {"$pop":{"students":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.class.findOne()
{
        "_id" : ObjectId("5854b5a0e7d717fcb974637b"),
        "班級" : "一班",
        "students" : [
                {
                        "name" : "bbb",
                        "age" : 2
                }
        ]
}
> 

$pull

有時需要基於特定條件來刪除,而不僅僅是依據元素位置,這時可以使用$pull。$pull會將所有匹配的文檔刪除,而不是只刪除一個。

> db.list.insert(
... {"todo":["dishes","laundry","dry cleaning"]})
WriteResult({ "nInserted" : 1 })
> db.list.update({},{"$pull":{"todo":"laundry"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.list.findOne()
{
        "_id" : ObjectId("585690afc5b0525a48a441b4"),
        "todo" : [
                "dishes",
                "dry cleaning"
        ]
}
> 

數組操作符只能用於包含數組值的鍵。例如:不能將一個整數插入數組,也不能將一個字元串從數組中彈出。要修改標量值,使用$set$inc。

基於位置的數組修改器

有兩種方法操作數組中的值:通過位置或者定位操作符($)

位置

通過數組位置來操作。數組都是以0開頭的,可以將下標直接作為鍵來選擇元素。

> db.blog.insert(
... {
...     "content": "...",
...     "comments": [
...         {
...             "comment": "good post",
...             "author": "john",
...             "votes": 0
...         },
...         {
...             "comment": "i thought it was too short",
...             "author": "claire",
...             "votes": 3
...         },
...         {
...             "comment": "free watches",
...             "author": "alice",
...             "votes": -1
...         }
...     ]
... })
WriteResult({ "nInserted" : 1 })

> db.blog.update({"content":"..."},{"$inc":{"comments.0.votes":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("585694e4c5b0525a48a441b5"),
        "content" : "...",
        "comments" : [
                {
                        "comment" : "good post",
                        "author" : "john",
                        "votes" : 1
                },
                {
                        "comment" : "i thought it was too short",
                        "author" : "claire",
                        "votes" : 3
                },
                {
                        "comment" : "free watches",
                        "author" : "alice",
                        "votes" : -1
                }
        ]
}
>

定位操作符$

如果無法知道要修改的數組的下標,可以使用定位操作符$,用來定位查詢文檔已經匹配的元素,併進行更新。

> db.blog.update(
... {"comments.author":"john"},
... {"$set":{"comments.$.author":"jim"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.findOne()
{
        "_id" : ObjectId("585694e4c5b0525a48a441b5"),
        "content" : "...",
        "comments" : [
                {
                        "comment" : "good post",
                        "author" : "jim",
                        "votes" : 1
                },
                {
                        "comment" : "i thought it was too short",
                        "author" : "claire",
                        "votes" : 3
                },
                {
                        "comment" : "free watches",
                        "author" : "alice",
                        "votes" : -1
                }
        ]
}
> 

upsert

upsertupdate()的第三個參數。表示沒有則創建,有則正常更新。

> db.analytics.update({"url":"/blog"},{"$inc":{"pageviews":1}},true)
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 1,
        "nModified" : 0,
        "_id" : ObjectId("58569d3cb6687ca8dfad4e01")
})
> db.analytics.findOne()
{
        "_id" : ObjectId("58569d3cb6687ca8dfad4e01"),
        "url" : "/blog",
        "pageviews" : 1
}
> db.analytics.update({"url":"/blog"},{"$inc":{"pageviews":1}},true)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>  db.analytics.findOne()
{
        "_id" : ObjectId("58569d3cb6687ca8dfad4e01"),
        "url" : "/blog",
        "pageviews" : 2
}
> 

$setOnInsert

在創建文檔的同時創建欄位併為它賦值,但是在之後的所有更新操作中在,這個欄位的值都不在改變。

$setOnInsert只會在文檔插入時設置欄位的值。

在預置或者初始化計數器時,或者對於不使用ObjectIds的集合來說,“$setOnInsert”是非常有用的。

> db.user.update({},{"$setOnInsert":{"createAt":new Date()}},true)
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 1,
        "nModified" : 0,
        "_id" : ObjectId("58569fe1b6687ca8dfad4e02")
})
> db.user.findOne()
{
        "_id" : ObjectId("58569fe1b6687ca8dfad4e02"),
        "createAt" : ISODate("2016-12-18T14:40:33.273Z")
}
> db.user.update({},{"$setOnInsert":{"createAt":new Date()}},true)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.user.findOne()
{
        "_id" : ObjectId("58569fe1b6687ca8dfad4e02"),
        "createAt" : ISODate("2016-12-18T14:40:33.273Z")
}
> 

save

一個shell函數,不存在創建,反之則更新文檔。

它只有一個參數:文檔。要是這個文檔含有“_id”鍵,save會調用upsert。否則會調用insert。在shell中快速對文檔進行修改。

> db.user.save({"x":10,"y":20})
WriteResult({ "nInserted" : 1 })
> var x=db.user.findOne()
> x.num=43
43
> db.user.save(x)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.findOne()
{
        "_id" : ObjectId("5856a230c5b0525a48a441be"),
        "x" : 10,
        "y" : 20,
        "num" : 43
}

更新多個文檔

預設情況下,只會更新匹配的第一個文檔。要更新多個文檔,需要將update的第4個參數設置為true

想要知道多文檔更

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 引言 提到前端往往很多人的映像就是入門簡單,HTML、CSS加一起一個星期基本上就能大概上手,JS難一點但也能很快寫一些簡單的小效果,在網上隨便一搜索各種特效代碼隨意用,一個新手前端也能在很短的時間里寫出炫酷的頁面效果,然而入門簡單並不意味著前端這碗飯很好吃,做慣了切圖、佈局、扣特效的前端新同學在向 ...
  • 直接插入排序演算法(Straight Insertion Sort),是排序演算法中簡單的一種演算法,基本思想如下: 將一個記錄插入到已排序好的有序表中,從而得到一個新,記錄數增1的有序表。即:先將序列的第1個記錄看成是一個有序的子序列,然後從第2個記錄逐個進行插入,直至整個序列有序為止。 要點:設立哨兵 ...
  • 本案例來自React.js中文官網對應內容。 一. 運行環境 二. 組件架構 App下有兩個子組件 (評論列表)和 (評論區),其中 下又有一個子組件 (評論) Comment包括一個h2的評論人名稱,一個span的評論內容,獲取數據之後,Comment組件以數組的形式傳入CommentList。 ...
  • 1.html 2.app.js ...
  • 1.定義變數:Sass中定義變數的關鍵字是'$'(畢竟程式員缺錢),並使用冒號(:)進行賦值,例如: $width:200px;//定義了一個名為width的變數,值為200px 2.普通變數和預設變數: 普通變數便是我們在大括弧外用上面的方式聲明的變數,可全局使用。 預設變數需要在聲明的變數後加上 ...
  • 關於排序,其實不管是哪種語言,都有它內置的排序函數,我們要用的時候調用就行了,既然如此,我們為什麼還要講這個東西呢?我想,其實,我們講排序更多是在於排序中包含的思想演算法,因為,演算法對於電腦來說相當重要,一個好的演算法能夠讓電腦的效率達到事半功倍的效果,所以,演算法是電腦語言中一門相當熱門的課程,它 ...
  • var http = require( 'http' ) var handlePaths = [] /** * 初始化路由配置數組 */ function initRotute() { handlePaths.push( '/' ) handlePaths.push( '/login' ) hand... ...
  • 1、相關環境 centos7 hadoop2.6.5 zookeeper3.4.9 jdk1.8 hbase1.2.4 本篇文章僅涉及hbase集群的搭建,關於hadoop與zookeeper的相關部署參見上篇文章http://www.cnblogs.com/learn21cn/p/6184490. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...