官方文檔地址:http://docs.mongodb.org/manual/applications/create/
創建
在數據庫中的四個基本操作(CRUD),創建操作是指那些把記錄或文檔集合添加到
MongoDB中的聚集中的操作。
概述:
你可以利用下面的任一基本操作在MongoDB中創建文檔集合:
insert
create with save
create with upsert
下列是MongoDB中所有的insert操作:
1.如果你試圖插入一條沒有_id字段的文檔,客戶端庫或mongod實例會自動添加_id字段並設置
將其填充給一個唯一的ObjectId字段!
2.對於寫相關的操作,如果你指定一個_id字段,那麼該_id字段在聚集中必須是唯一的;否則,
mongod會返回一個duplicate key exception。
3.BSON文檔的最大大小事16MB。
文檔類型的最大值有助於確定一個單獨的文檔不能佔用過多的內存以及在傳輸過程中佔用過多的帶寬。
爲了保存大於最大值的文檔,MongoDB提供了GridFSB API。
4.文檔在字段名稱上有如下的約束:
1.字段_id是預留的用作主鍵的字段,字段的值必須是在聚集中唯一的,不變的,並且可以使除了數組
的其他任何類型。
2.字段名不能以$開始。
3.字段名稱不能包含.。
注意:以下的驅動版本中,所有的寫相關操作都會發出一個getLastError命令,來確認寫操作的結果:
C#, version 0.7
Java, version 2.10.0
Node.js, version 1.2
Perl, version 0.601.1
PHP, version 1.4
Python, version 2.4
Ruby, version 1.8
{getLastError:1}
1.插入操作
insert()是將一個或多個文檔插入到MongoDB聚集中的基本方法,該方法有如下的句式:
db.collection.insert( <document> )
SQL中類似的操作:insert()類似於INSERT操作!
下面的示例演示了insert()的用法:
1.如果聚集並不存在(你可以在mongo shell中通過show collections 操作來列出存在的聚集),
insert()方法會在第一次插入數據的時候創建聚集。如下所示:如果聚集bios不存在,insert操作
會創建這個聚集:
db.bios.insert(
{
_id: 1,
name: { first: 'John', last: 'Backus' },
birth: new Date('Dec 03, 1924'),
death: new Date('Mar 17, 2007'),
contribs: [ 'Fortran', 'ALGOL', 'Backus-Naur Form', 'FP' ],
awards: [
{
award: 'W.W. McDowell Award',
year: 1967,
by: 'IEEE Computer Society'
},
{
award: 'National Medal of Science',
year: 1975,
by: 'National Science Foundation'
},
{
award: 'Turing Award',
year: 1977,
by: 'ACM'
},
{
award: 'Draper Prize',
year: 1993,
by: 'National Academy of Engineering'
}
]
}
)
你可以通過查詢bios來確認insert的操作結果:
db.bios.find()
操作會返回如下數據:
{
"_id" : 1,
"name" : { "first" : "John", "last" : "Backus" },
"birth" : ISODate("1924-12-03T05:00:00Z"),
"death" : ISODate("2007-03-17T04:00:00Z"),
"contribs" : [ "Fortran", "ALGOL", "Backus-Naur Form", "FP" ],
"awards" : [
{
"award" : "W.W. McDowell Award",
"year" : 1967,
"by" : "IEEE Computer Society"
},
{
"award" : "National Medal of Science",
"year" : 1975,
"by" : "National Science Foundation"
},
{
"award" : "Turing Award",
"year" : 1977,
"by" : "ACM"
},
{ "award" : "Draper Prize",
"year" : 1993,
"by" : "National Academy of Engineering"
}
]
}
2.如果新的文檔不包含_id字段,insert會添加這個字段並且爲其生成一個唯一的ObjectId:
db.bios.insert(
{
name: { first: 'John', last: 'McCarthy' },
birth: new Date('Sep 04, 1927'),
death: new Date('Dec 24, 2011'),
contribs: [ 'Lisp', 'Artificial Intelligence', 'ALGOL' ],
awards: [
{
award: 'Turing Award',
year: 1971,
by: 'ACM'
},
{
award: 'Kyoto Prize',
year: 1988,
by: 'Inamori Foundation'
},
{
award: 'National Medal of Science',
year: 1990,
by: 'National Science Foundation'
}
]
}
)
你可以通過以下操作覈實insert的行爲:
db.bios.find({name:{first:'John',last:'McCarthy'}})
返回的結果中自動產生了一個唯一的_id字段:
{
"_id" : ObjectId("50a1880488d113a4ae94a94a"),
"name" : { "first" : "John", "last" : "McCarthy" },
"birth" : ISODate("1927-09-04T04:00:00Z"),
"death" : ISODate("2011-12-24T05:00:00Z"),
"contribs" : [ "Lisp", "Artificial Intelligence", "ALGOL" ],
"awards" : [
{
"award" : "Turing Award",
"year" : 1971,
"by" : "ACM"
},
{
"award" : "Kyoto Prize",
"year" :1988,
"by" : "Inamori Foundation"
},
{
"award" : "National Medal of Science",
"year" : 1990,
"by" : "National Science Foundation"
}
]
}
3.如果你傳遞一個數組到insert(),insert()會對聚集產生一個批量的插入!
接下來的操作向bios聚集中插入了3個文檔,這個操作同樣也闡述了MongoDB中
動態模式的特性,儘管_id:3的文檔中有一個title字段是其他2個文檔中沒有的,
MongoDB也不多強制要求其他文檔包含次屬性:
db.bios.insert(
[
{
_id: 3,
name: { first: 'Grace', last: 'Hopper' },
title: 'Rear Admiral',
birth: new Date('Dec 09, 1906'),
death: new Date('Jan 01, 1992'),
contribs: [ 'UNIVAC', 'compiler', 'FLOW-MATIC', 'COBOL' ],
awards: [
{
award: 'Computer Sciences Man of the Year',
year: 1969,
by: 'Data Processing Management Association'
},
{
award: 'Distinguished Fellow',
year: 1973,
by: ' British Computer Society'
},
{
award: 'W. W. McDowell Award',
year: 1976,
by: 'IEEE Computer Society'
},
{
award: 'National Medal of Technology',
year: 1991,
by: 'United States'
}
]
},
{
_id: 4,
name: { first: 'Kristen', last: 'Nygaard' },
birth: new Date('Aug 27, 1926'),
death: new Date('Aug 10, 2002'),
contribs: [ 'OOP', 'Simula' ],
awards: [
{
award: 'Rosing Prize',
year: 1999,
by: 'Norwegian Data Association'
},
{
award: 'Turing Award',
year: 2001,
by: 'ACM'
},
{
award: 'IEEE John von Neumann Medal',
year: 2001,
by: 'IEEE'
}
]
},
{
_id: 5,
name: { first: 'Ole-Johan', last: 'Dahl' },
birth: new Date('Oct 12, 1931'),
death: new Date('Jun 29, 2002'),
contribs: [ 'OOP', 'Simula' ],
awards: [
{
award: 'Rosing Prize',
year: 1999,
by: 'Norwegian Data Association'
},
{
award: 'Turing Award',
year: 2001,
by: 'ACM'
},
{
award: 'IEEE John von Neumann Medal',
year: 2001,
by: 'IEEE'
}
]
}
]
)
2.通過save創建
save()方法是一個特殊的方法,它使用<document>的_id字段來決定插入或者更新一個文檔。
1.如果<document>參數不包含_id字段或者包含的_id字段的值並不在聚集中,save()方法會表現
插入操作。
2.否則,save()方法會表現爲更新操作。
save()方法的句法如下:
db.collection.save( <document> )
通過下面的示例來思考save()方法在插入操作方面的用法:
1.如果<document>不包含_id字段,save()方法會表現爲插入.
具體實現參照“插入操作“中對於不包含_id字段文檔的插入操作的詳細說明。
下面的操作展示了<document>不包含_id字段的時候save()方法表現出來的插入行爲:
db.bios.save(
{
name: { first: 'Guido', last: 'van Rossum'},
birth: new Date('Jan 31, 1956'),
contribs: [ 'Python' ],
awards: [
{
award: 'Award for the Advancement of Free Software',
year: 2001,
by: 'Free Software Foundation'
},
{
award: 'NLUUG Award',
year: 2003,
by: 'NLUUG'
}
]
}
)
2.如果<document>包含_id字段但是字段的值在聚集中沒有找到,save()方法也會表現出插入操作。
具體實現參照“插入操作“中插入操作的詳細說明。
下面的操作展示了將一個文檔插入到bios聚集中,但是該文檔所包含的_id字段的數值10在bios聚集中
無法找到的情況:
db.bios.save(
{
_id: 10,
name: { first: 'Yukihiro', aka: 'Matz', last: 'Matsumoto'},
birth: new Date('Apr 14, 1965'),
contribs: [ 'Ruby' ],
awards: [
{
award: 'Award for the Advancement of Free Software',
year: '2011',
by: 'Free Software Foundation'
}
]
}
)
3.通過upsert創建
一個upsert消除了一條在一個獨立數據庫中的記錄在插入或更新之前調用檢查其是否存在的需要。(原文:
An upsert eliminates the need to perform a separate database call to check for the existence of a record before performing either an update or an insert operation.)
傳統的update操作會更新已存在的文檔模型,但是在MongoDB中,update()操作可以接受<upsert>操作作爲一個參數
,upsert是一個調用<query>參數來決定寫操作的混合操作:
1.如果query匹配到一個或多個已然存在的文檔,upsert會表現爲更新操作。
2.如果query在聚集中沒有匹配到文檔,則erpsert會插入一個獨立的文檔。
通過下面的句法思考upsert的操作:
db.collection.update( <query>,
<update>,
{ upsert: true } )
接下來的例子闡述了upsert表現爲create的操作:
1.如果沒有文檔匹配到<query>參數,upsert表現爲插入操作,如果<update>參數僅包含字段和數值對,則新文檔
包含<update>參數中指定的所有字段和值,如果_id字段被省略了,那麼添加操作會自動產生一個
唯一的ObjectId來填充_id字段(唯一的哦)!
下面的upsert操作箱bios聚集中插入了一個新的文檔:
db.bios.update(
{ name: { first: 'Dennis', last: 'Ritchie'} },
{
name: { first: 'Dennis', last: 'Ritchie'},
birth: new Date('Sep 09, 1941'),
died: new Date('Oct 12, 2011'),
contribs: [ 'UNIX', 'C' ],
awards: [
{
award: 'Turing Award',
year: 1983,
by: 'ACM'
},
{
award: 'National Medal of Technology',
year: 1998,
by: 'United States'
},
{
award: 'Japan Prize',
year: 2011,
by: 'The Japan Prize Foundation'
}
]
},
{ upsert: true }
)
2.如果<query>參數沒有匹配到文檔,upsert操作會插入一個新的文檔,如果<update>參數只是
包含對已有文檔對象的修改,那麼新誕生的文檔會包含<query>參數中已有的字段和<update>
參數中更新的字段!
下面的操作在bios聚集中插入了一個新文檔:
db.bios.update(
{
_id: 7,
name: { first: 'Ken', last: 'Thompson' }
},
{
$set: {
birth: new Date('Feb 04, 1943'),
contribs: [ 'UNIX', 'C', 'B', 'UTF-8' ],
awards: [
{
award: 'Turing Award',
year: 1983,
by: 'ACM'
},
{
award: 'IEEE Richard W. Hamming Medal',
year: 1990,
by: 'IEEE'
},
{
award: 'National Medal of Technology',
year: 1998,
by: 'United States'
},
{
award: 'Tsutomu Kanai Award',
year: 1999,
by: 'IEEE'
},
{
award: 'Japan Prize',
year: 2011,
by: 'The Japan Prize Foundation'
}
]
}
},
{ upsert: true }
)