MongoDB for Java Programmer ——2

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": "tt0075
148"});
{
        "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 masterp
iece 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, isolat
ed, atrophied West Texas town that is slowly dying, both economically and cultur
ally.",
        "poster" : "http://ia.media-imdb.com/images/M/MV5BNDkyNzQ1NzYzN15BMl5Ban
BnXkFtZTcwNjE5MDEwNw@@._V1._CR73.19999694824219,89.69999694824219,1196,1865.2000
274658203_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 dysfu
nctional life during a doomed romance that also inspires him.",
        "poster" : "http://ia.media-imdb.com/images/M/MV5BMTU0NDc5NjgzNl5BMl5Ban
BnXkFtZTcwNzc0NDIzMw@@._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 Bri
dges, Crazy Heart transcends its overly familiar origins and finds new meaning i
n 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 c
reates a unique weaponized suit of armor to fight evil.",
        "poster" : "http://ia.media-imdb.com/images/M/MV5BMTczNTI2ODUwOF5BMl5Ban
BnXkFtZTcwMTU0NTIzMw@@._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. m
ake this smart, high impact superhero movie one that even non-comics fans can en
joy.",
                "userMeter" : 91,
                "userRating" : 4.2,
                "userReviews" : 1072887
        },
        "metacritic" : 79,
        "awards" : {
                "wins" : 19,
                "nominations" : 58,
                "text" : "Nominated for 2 Oscars. Another 19 wins & 58 nominatio
ns."
        },
        "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 Sax
on masses in King Richard's absence, a Saxon lord fights back as the outlaw lead
er of a rebel guerrilla army.",
        "poster" : "http://ia.media-imdb.com/images/M/MV5BMTUxMzE0MjI0MF5BMl5Ban
BnXkFtZTcwMTQ1OTM2MQ@@._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表示返回除这个字段之外的其他字段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值