MongoDB for Java Programmer ——2

来源:互联网 发布:社会网络的同义词 编辑:程序博客网 时间:2024/06/05 15:14

CRUD

在关系型数据库中,如果一个字段没有有效值,我们通常会初始化默认值(当然也可以存NULL),但在MongoDB中,我们可以不存储这个字段即可.这就是所谓的schema-less

Creating documents in mongodb

    - db.mycoll.insertOne(document, <optional params>)     - db.mycoll.insertMany( [documents], <optional params> ) 

第二个参数如果是 “ordered”:false 则表示非顺序插入,其中某个document遇到异常,不影响其他document的插入。默认为True,顺序插入,会在错误处中断执行,则后续操作就不会执行了。

  • upsert (如果存在重复的先更新,否则直接插入。这种创建document的方式不详述)

每次插入document(一条数据),这个数据必须有一个“_id”字段,默认是自动生成一个唯一的ObjectId(…),也可以手动指定一个唯一的数据。类似于传统数据库中的自增主键。
以上所说的“唯一”是在单个个collection中唯一,类似于传统数据库表的自增主键唯一,也只是这个table中唯一。
如下实例,可以看到“_id”除了自动生成,也可以手动设置(不建议手动设置,原因看后文)。

> db.elementMatch.insertMany([{result:[82,85,88]},{result:[75,88,89]}]){        "acknowledged" : true,        "insertedIds" : [                ObjectId("57558318c700c2881f75fef6"),                ObjectId("57558318c700c2881f75fef7")        ]}> db.moviesScratch.insertOne({ "title": "Rocky", "year": "1976", "imdb": "tt0075148"});{        "acknowledged" : true,        "insertedId" : ObjectId("5753c0eeeb62b409398b67ac")}> db.moviesScratch.insertOne({ "title": "Rocky", "year": "1976", "imdb": "tt0075", "_id":"10001"}){ "acknowledged" : true, "insertedId" : "10001" }> db.moviesScratch.find({"title":"Rocky"}).pretty(){        "_id" : ObjectId("5753bcd0d72e989351cbf22a"),        "title" : "Rocky",        "year" : "1976",        "imdb" : "tt0075148"}{        "_id" : ObjectId("5753c0eeeb62b409398b67ac"),        "title" : "Rocky",        "year" : "1976",        "imdb" : "tt0075148"}{ "_id" : "10001", "title" : "Rocky", "year" : "1976", "imdb" : "tt0075" }

详解_id字段

默认情况下,每个collection(表)都会在“_id”字段上有一个聚簇索引(可理解为主键索引)。并且这字段的默认类型是OjbectId.

{ "_id" : ObjectId("5753e1bfeb62b409398b67c1"), ...... }{ "_id" : ObjectId("5753e1e9eb62b409398b67c2"),......}

ObjetcId是一个12byte的16进制字符串组成如下:

这里写图片描述

Reading Documents

  • db.mycoll.find([query],[fields])
    • query is an optional query filter. fields is optional set of fields to return.
      e.g.
      db.mycoll.find( {x:77} , {name:1, x:1} )
      ……………
      db.mycoll.find(…).count()
      db.mycoll.find(…).limit(n)
      db.mycoll.find(…).skip(n)
      db.mycoll.find(…).sort(…)
      db.mycoll.findOne([query], [fields], [options], [readConcern])
> db.movieDetails.find({"rated":"PG-13"}).count()153> db.movieDetails.find({"rated":"PG-13","year":2009}).count()8

如何选择性读取内嵌fields

{    {....        {            "fieldOuterN": {                ...,"fieldInner": value            }        }  ....}}

如果要通过内嵌结构的字段查找,比如以下document中tomato字段中的meter等字段,使用如下方式 db.mycoll.find({“fieldOuterN.fieldInner” : value,……})

> db.movieDetails.findOne(){        "_id" : ObjectId("569190ca24de1e0ce2dfcd4f"),        "title" : "Once Upon a Time in the West",        "year" : 1968,        "rated" : "PG-13",        "released" : ISODate("1968-12-21T05:00:00Z"),        "runtime" : 175,        "countries" : [                "Italy",                "USA",                "Spain"        ],        "genres" : [                "Western"        ],..........        "tomato" : {                "meter" : 98,                "image" : "certified",                "rating" : 9,                "reviews" : 54,                "fresh" : 53,                "consensus" : "A landmark Sergio Leone spaghetti western masterpiece featuring a classic Morricone score.",                "userMeter" : 95,                "userRating" : 4.3,                "userReviews" : 64006        },        "metacritic" : 80,        "awards" : {                "wins" : 4,                "nominations" : 5,                "text" : "4 wins & 5 nominations."        },        "type" : "movie"}> db.movieDetails.find({"tomato.rating":100}).count()0> db.movieDetails.find({"tomato.meter":100}).count()8

如何选择性读取数组类型value

一般有以下几种读取场景:

  • 过滤读取 整个数组
    比如,读取 “writers” 字段值为 [“Ethan Coen”, “Joel Coen”]的document.(元素顺序、个数、内容等等完全匹配)
> db.movieDetails.find({"writers":["Ethan Coen","Joel Coen"]}).pretty(){        "_id" : ObjectId("5692a14f24de1e0ce2dfcf60"),        "title" : "The Big Lebowski",        "year" : 1998,        "rated" : "R",        "released" : ISODate("1998-03-06T05:00:00Z"),        "runtime" : 117,        "countries" : [                "USA",                "UK"        ],        "genres" : [                "Comedy",                "Crime"        ],        "director" : "Joel Coen, Ethan Coen",        "writers" : [                "Ethan Coen",                "Joel Coen"        ],        "actors" : [                "Jeff Bridges",                "John Goodman",                "Julianne Moore",                "Steve Buscemi"        ],     ........................        "type" : "movie"}
  • 过滤读取 数组中任一个元素
    查找writers数组字段中含有 “Jeff Bridges”的所有document
> db.movieDetails.find({"actors":"Jeff Bridges"}).pretty(){        "_id" : ObjectId("569190d124de1e0ce2dfcd86"),        "title" : "The Last Picture Show",        "year" : 1971,        "rated" : "R",        "released" : ISODate("1971-10-22T04:00:00Z"),        "runtime" : 118,        "countries" : [                "USA"        ],        "genres" : [                "Drama"        ],        "director" : "Peter Bogdanovich",        "writers" : [                "Larry McMurtry",                "Peter Bogdanovich",                "Larry McMurtry"        ],        "actors" : [                "Timothy Bottoms",                "Jeff Bridges",                "Cybill Shepherd",                "Ben Johnson"        ],        "plot" : "A group of 1950s high schoolers come of age in a bleak, isolated, atrophied West Texas town that is slowly dying, both economically and culturally.",        "poster" : "http://ia.media-imdb.com/images/M/MV5BNDkyNzQ1NzYzN15BMl5BanBnXkFtZTcwNjE5MDEwNw@@._V1._CR73.19999694824219,89.69999694824219,1196,1865.2000274658203_SX89_AL_.jpg_V1_SX300.jpg",        "imdb" : {                "id" : "tt0067328",                "rating" : 8.1,                "votes" : 29830        },        "awards" : {                "wins" : 16,                "nominations" : 22,                "text" : "Won 2 Oscars. Another 16 wins & 22 nominations."        },        "type" : "movie"}..............................{        "_id" : ObjectId("5692a14e24de1e0ce2dfcf56"),        "title" : "Crazy Heart",        "year" : 2009,        "rated" : "R",        "released" : ISODate("2010-02-05T05:00:00Z"),        "runtime" : 112,        "countries" : [                "USA"        ],        "genres" : [                "Drama",                "Music",                "Romance"        ],        "director" : "Scott Cooper",        "writers" : [                "Scott Cooper",                "Thomas Cobb"        ],        "actors" : [                "Jeff Bridges",                "James Keane",                "Anna Felix",                "Paul Herman"        ],        "plot" : "A faded country music musician is forced to reassess his dysfunctional life during a doomed romance that also inspires him.",        "poster" : "http://ia.media-imdb.com/images/M/MV5BMTU0NDc5NjgzNl5BMl5BanBnXkFtZTcwNzc0NDIzMw@@._V1_SX300.jpg",        "imdb" : {                "id" : "tt1263670",                "rating" : 7.3,                "votes" : 63771        },        "tomato" : {                "meter" : 91,                "image" : "certified",                "rating" : 7.4,                "reviews" : 199,                "fresh" : 181,                "consensus" : "Thanks to a captivating performance from Jeff Bridges, Crazy Heart transcends its overly familiar origins and finds new meaning in an old story.",                "userMeter" : 76,                "userRating" : 3.6,                "userReviews" : 124175        },        "metacritic" : 83,        "awards" : {                "wins" : 32,                "nominations" : 26,                "text" : "Won 2 Oscars. Another 32 wins & 26 nominations."        },        "type" : "movie"}>
  • 过滤读取 数组中指定的某位置的者某特定元素
    比如我要查找actors字段的第三个元素为“Jeff Bridges”的document。
find({"actors.2":"Jeff Bridges"})
> db.movieDetails.find({"actors.2":"Jeff Bridges"}).pretty(){        "_id" : ObjectId("5692a15424de1e0ce2dfcf98"),        "title" : "Iron Man",        "year" : 2008,        "rated" : "PG-13",        "released" : ISODate("2008-05-02T04:00:00Z"),        "runtime" : 126,        "countries" : [                "USA"        ],        "genres" : [                "Action",                "Adventure",                "Sci-Fi"        ],        "director" : "Jon Favreau",        "writers" : [                "Mark Fergus",                "Hawk Ostby",                "Art Marcum",                "Matt Holloway",                "Stan Lee",                "Don Heck",                "Larry Lieber",                "Jack Kirby"        ],        "actors" : [                "Robert Downey Jr.",                "Terrence Howard",                "Jeff Bridges",                "Gwyneth Paltrow"        ],        "plot" : "After being held captive in an Afghan cave, an industrialist creates a unique weaponized suit of armor to fight evil.",        "poster" : "http://ia.media-imdb.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw@@._V1_SX300.jpg",        "imdb" : {                "id" : "tt0371746",                "rating" : 7.9,                "votes" : 641369        },        "tomato" : {                "meter" : 94,                "image" : "certified",                "rating" : 7.7,                "reviews" : 266,                "fresh" : 249,                "consensus" : "Director Jon Favreau and star Robert Downey Jr. make this smart, high impact superhero movie one that even non-comics fans can enjoy.",                "userMeter" : 91,                "userRating" : 4.2,                "userReviews" : 1072887        },        "metacritic" : 79,        "awards" : {                "wins" : 19,                "nominations" : 58,                "text" : "Nominated for 2 Oscars. Another 19 wins & 58 nominations."        },        "type" : "movie"}>
  • 更复杂的匹配读取,后文中再讨论

CURSOR指针

前文说过,在shell中,db.mycoll.find()返回是一个指针对象。而且默认情况下,每次返回内容默认是这个指针对象遍历20次的内容集合。

.......Type "it" for more

通过使用it再次遍历20次,并返回20次的总结果集合。

通常,mongoDB是以batches(批量)方式返回查询集合。对于大多数查询,第一个批量返回101条document.比如:
第一个批量总共返回101条document,第二个批量返回剩余的21条document。

> db.funnynumbers.find().count()122> var iterator=db.funnynumbers.find();> var eachDoc=function(){return iterator.hasNext()?iterator.next():null}> iterator.objsLeftInBatch()101> eachDoc(){ "_id" : ObjectId("50778ce69331a280cf4bcf7d"), "value" : 87 }> iterator.objsLeftInBatch()100> eachDoc(){ "_id" : ObjectId("50778ce69331a280cf4bcf7e"), "value" : 34 }> iterator.objsLeftInBatch()99

Projection

一种实现部分缩减返回数据的手段(通常针对单个查询)。通过减少返回document中的fields,来减少网络开销以及系统负载。
通常 Projection通过设置db.mycoll.find({},{})的第二个参数来实现。

比如:我要只返回(过滤:tomato字段中的meter字段为100的)document中的awards字段(可以看到“_id”并没有限制住,默认返回)。

> db.movieDetails.findOne({"tomato.meter":100},{"awards":1}){        "_id" : ObjectId("569190d024de1e0ce2dfcd79"),        "awards" : {                "wins" : 2,                "nominations" : 2,                "text" : "Won 3 Oscars. Another 2 wins & 2 nominations."        }}>>> db.movieDetails.findOne({"tomato.meter":100},{type:0,tomato:0,writers:0,actors:0,"_id":0,countries:0,genres:0}){        "title" : "The Adventures of Robin Hood",        "year" : 1938,        "rated" : "PG",        "released" : ISODate("1938-05-14T04:00:00Z"),        "runtime" : 102,        "director" : "Michael Curtiz, William Keighley",        "plot" : "When Prince John and the Norman Lords begin oppressing the Saxon masses in King Richard's absence, a Saxon lord fights back as the outlaw leader of a rebel guerrilla army.",        "poster" : "http://ia.media-imdb.com/images/M/MV5BMTUxMzE0MjI0MF5BMl5BanBnXkFtZTcwMTQ1OTM2MQ@@._V1_SX300.jpg",        "imdb" : {                "id" : "tt0029843",                "rating" : 8,                "votes" : 37543        },        "metacritic" : 97,        "awards" : {                "wins" : 2,                "nominations" : 2,                "text" : "Won 3 Oscars. Another 2 wins & 2 nominations."        }}>>> db.movieDetails.findOne({"tomato.meter":100},{"awards":1,_id:0}){        "awards" : {                "wins" : 2,                "nominations" : 2,                "text" : "Won 3 Oscars. Another 2 wins & 2 nominations."        }}

所以:
find()第二参数:{“awards”:1,”_id”:0}:
1表示只有这个字段需要返回(“_id”默认返回);
0表示返回除这个字段之外的其他字段。

0 0