分享

MongoDB是什么,有什么特点,该如何入门

howtodown 发表于 2014-1-4 22:23:21 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 38599
本帖最后由 howtodown 于 2014-1-4 22:28 编辑

1.MongoDB是什么
MongoDB是一个开源的,高性能,无模式(或者说是模式自由),使用C++语言编写的面向文档的数据库。正因为MongoDB是面向文档的,所以它可以管理类似JSON的文档集合。又因为数据可以被嵌套到复杂的体系中并保持可以查询可索引,这样一来,应用程序便可以以一种更加自然的方式来为数据建模。
MongoDB的特点
   1 统一的UTF-8编码
      不是UTF-8编码集合的数据也可以通过使用一种特殊的二进制数据类型来保存,查询。
   2 跨平台支持
      二进制文件可以再Windows,Linux,OS X和Solaris平台上使用。MongoDB可以在大多数小端系统上编译通过。
   3 支持丰富的类型
      支持 dates, regular expressions, code, binary data 等类型
   4 查询结果支持Cursor操作
   5 支持Ad hoc queries(Ad hoc query:即席查询,数据库应用最普遍的一种查询,利用数据仓库技术,可以让用户随时可以面对数据库,获取所希望的数据。
      在MongoDB中,可以在任何时候查询任何一个field。它支持 range queries,regular expression searches 和其他特殊的查询类型。同时查询也可以包含用户定义的javascript函数。
   6  支持嵌套域的查询
       查询可以深入到嵌套的对象和数组中,如果下面的对象被插入到users集合:
       {
               "username" : "bob",
               "address" : {
                      "street" : "123 Main Street",
                      "city" : "Springfield",
                      "state" : "NY"
                 }
        }
       我们可以这样查询嵌套在里层的域
       db.users.find({“address.state”:"NY”})
       数组元素则可以被这样查询:
       > db.food.insert({"fruit" : ["peach", "plum", "pear"]})
       > db.food.find({"fruit" : "pear"})
   7 支持索引
       支持二级索引包括 single-key, compound, unique, non-unique, geospatial indexes.嵌套的域同样也可以被索引。如果我们对一个数组类型进行索引,那么数组中所有元素也会自动被索引。
    当一个查询执行时,MongoDB的查询优化器会尝试多个不同的query plan,并选择执行速度最快的。开发者可以通过explain功能看到索引被使用的过程,然后可以通过hint功能来选择另一个不同的索引。
       可以在任何时候创建和删除索引
   8 aggregation
       除了ad hoc queries外,MongoDB还支持一系列工具来支持聚合,例如MapReduce和其他类似于SQL的GROUP BY的函数集合。
   9 文件存储
       该软件实现了一个称为GridFS的协议,这个协议是用来帮助从数据库中存储和获取文件的。
   10 支持服务器端javascript执行
        javaScript是MongoDB的一种通用语言,它可以被用在查询,聚集函数,直接由数据库执行。
        下面是一个使用javascript的查询例子:
         db.foo.find({$where:function(){return this.x==this.y;}})
        发送代码到数据库执行:
         db.eval(function(name){return “Hello, ”+name;},[“Joe”])
        javaScript的变量可以被存储在数据库中并被其他javas作为全局变量使用。任何合法的javascript类型包括函数和对象,都可以被存储在MongoDB中,所以javascript可以被用来写<存储过程>
    11 capped collection
         MongoDB支持被称为capped collections(定量集合)的定长集合。Capped collections是唯一一种维持插入顺序的集合,其中,如果达到容量最大值,那么就会覆盖第一个元素,也就是说capped collection的行为类似于一个环形队列。
         一种特殊的cursor类型,称为tailable cursor,可以被用在capped collection上,当完成结果返回时,这种cursor不会关闭,而是会继续等待更多的结果来返回。也就是说如果有新的记录插入到capped collection的话,cursor会自动返回。
   12 目前提供多种语言的driver
  13 部署
        MongoDB使用的是memory-mapped files(内存映射文件:A memory-mapped file is a segment of virtual memory which has been assigned a direct byte-for-byte correlation with some portion of a file or file-like resource. This resource is typically a file that is physically present on-disk, but can also be a device, shared memory object, or other resource that the operating system can reference through a file descriptor. Once present, this correlation between the file and the memory space permits applications to treat the mapped portion as if it were primary memory. ,在32位机器上限制数据的最大大小为2GB,同时MongoDB服务器只能在小端系统上运行。
    14 Replication
      MongoDB不应被部署到少于两台的服务器上,也就是说至少有一台作为master,另一台作为slave。Master可以用来执行读写,而slave可以从master上复制数据,但是它只能执行读操作或备份操作。开发者可以根据情况让一个operation可以被replicate到多个servers上。
       下面的代码是启动一个master服务器和对应的slave服务器
       $ mkdir –p ~/dbs/master ~/dbs/slave
       $ ./mongod –master –port 10000 –dbpath ~/dbs/master
       $ ./mongod –slave  --port10001 –dbpath ~/dbs/slave  -- source localhost:10000

如何入门:

从官网上下载最新版本的数据库mongodb-1.4.1到本地,解压后,运行bin目录下的mongod.exe不过需要在命令行下运行,为了方便,写了个bat文件

  1. @echo off
  2. cd bin
  3. mongod -dbpath "E:\dbdata" run
复制代码
只要运行这个bat就可以启动服务器了,默认端口在27017。
    那么客户端呢,自带的客户端是mongo.exe这个程序,直接打开就默认的连接到本地的数据库。下面可以在这个shell里写命令,
    show dbs,列出所有的数据库,use test,使用test这个数据库,怎么创建一个数据库呢?use newdb就可以了,如果newdb存在则不创建,不存在则创建,但这个时候如果继续show dbs发现没有newdb,怎么办,执行show collections 再show dbs发现newdb存在了,原来use newdb并不立即产生,只有在使用这个newdb后才产生.
    同样,现在新建一个集合,使用db.newCol.save({})在创建一个数据后则自动创建这个newCol集合,现在使用show collections可以看见newCol了,save()括号里的是数据对象,是一个json格式的数据,比如我们想存入用户名和密码可以这样,db.user.save({userName:"testU",userPwd:"123456"}),然后执行db.user.find(),列出所有记录,{ "_id" : ObjectId("4bcadb0b8a76000000001b08"), "userName" : "testU", "userPwd"
: "123456" },可以看到输出结果也是json格式,因此在使用json的场合很适用。
      想获得帮助,可以使用db.foo.help()列出所有对集合的操作。
      db.foo.remove()是用来删除数据,只删除匹配的对象
      db.foo.update({},{})更新对象,第一个参数是查询对象,第二个是替代的,可以在第二个对象里指定更新哪些字段,要使用$set。
      也可以分页,db.foo.find()有limit和skip2,使用这个2个就可以分页查询了。
      总的来说,使用mongodb可以满足常见的增删改差,但是不能完成复杂的跨表级联查询,mongodb努力使数据变得简单紧凑,因为你可以db.user.save({userName:"dd"})也可以db.user.save({userName:"ff",pwd:"123"}),这样第一个数据没有密码,而第二个有密码,2个数据没有关系的。
      我在封装时使用java反射机制,将一个model解读为DBObject格式存储,读数据时一样再反射为model。
       官网提供有javaAPI供下载,使用该API





1 建立连接
要建立MongoDB的连接,你只要指定要连接到的数据库就可以。这个数据库不一定存在,如果不存在,MongoDB会先为你建立这个

库。同时,在连接时你也可以具体指定要连接到的网络地址和端口。下面的是连接本机数据库的一些例子:

  1. import com.mongodb.Mongo;
  2. import com.mongodb.DBCollection;
  3. import com.mongodb.BasicDBObject;
  4. import com.mongodb.DBObject;
  5. import com.mongodb.DBCursor;
  6. import com.mongodb.MongoAdmin;
  7. Mongo db = new Mongo("mydb");
  8. Mongo db = new Mongo("localhost", "mydb");
  9. Mongo db = new Mongo("localhost", 27017, "mydb");
复制代码
2 安全验证(非必选)
MongoDB服务可以在安全模式运行,此时任何客户端要连接数据库时需使用用户名和密码。在JAVA中可使用如下方法连接:

  1. boolean auth = db.authenticate(userName, password);
复制代码
如果用户名密码验证通过,返回值为true,否则为false

3 获取集合列表
每个数据库都存在零个或多个集合,需要时你可以获得他们的列表:

  1. Set colls = db.getCollectionNames();
  2. for(String s : colls){
  3. System.out.println(s);
  4. }
复制代码
4 获得一个集合
要获得某个特定集合,你可以指定集合的名字,并使用getCollection()方法:

  1. DBCollection coll = db.getCollection("testCollection");
复制代码
当你获取了这个集合对象,你就可以对数据进行增删查改之类的操作。

5 插入文档
当你获得了一个集合对象,你就可以把文档插入到这个对象中。例如,存在一个JSON式的小文档:
{
"name" : "MongoDB",
"type" : "database",
"count" : 1,
"info" : {
x : 203,
y : 102
}
}
请注意,这个文档包含一个内部文档。我们可以使用BasicDBObject类来创建这个文档,并且使用insert()方法方便地将它插入到集

合中。

  1. BasicDBObject doc = new BasicDBObject();
  2. doc.put("name", "MongoDB");
  3. doc.put("type", "database");
  4. doc.put("count", 1);
  5. BasicDBObject info = new BasicDBObject();
  6. info.put("x", 203);
  7. info.put("y", 102);
  8. doc.put("info", info);
  9. coll.insert(doc);
复制代码
6 使用findOne()查找集合中第一个文档
要查找我们上一步插入的那个文档,可以简单地使用findOne()操作来获取集合中第一个文档。这个方法返回一个单一文档(这是相对于使用DBCursor的find()操作的返回),这对于只有一个文档或我们刚插入第一个文档时很有用,因为此时并不需要使用光标。



  1. DBObject myDoc = coll.findOne();
  2. System.out.println(myDoc);
复制代码
返回类似:
{
"_id" : "ac907a1f5b9d5e4a233ed300" ,
"name" : "MongoDB" ,
"type" : 1 ,
"info" : {
"x" : 203 ,
"y" : 102} ,
"_ns" : "testCollection"
}

注意_id和_ns元素是由MongoDB自动加入你的文档。记住:MongoDB内部存储使用的元素名是以“_”做为开始。

7 加入多种文档
为了做更多有趣的查询试验,让我们向集合中加入多种文档类型,象:
{
"i" : value
} 可以通过循环来实现

  1. for(int i = 0; i < 100; i++){
  2. coll.insert(new BasicDBObject().append("i", i));
  3. }
复制代码
注意我们可以在一个集合中插入不同类型的文档,这就是我们所说的“模式自由”(schema-free)。

8 统计文档数量
使用getCount()方法

  1. System.out.println(coll.getCount());
复制代码
9 使用光标(cursor)来获取全部文档
为了获取集合中的所有文档,我们可以使用find()方法。这个方法返回一上DBCursor对象,来允许我们将符合查询条件的文档迭代

出来。

  1. DBCursor cur = coll.find();
  2. while(cur.hasNext()){
  3. System.out.println(cur.next());
  4. }
复制代码
10 在查询中获取单一文档
我们可以创建一个查询,并传递给find()方法来获取集合中所有文档的一个子集。例如,我们想要查询域名为"i",并且值为71的文档:

  1. BasicDBObject query = new BasicDBObject();
  2. query.put("i", 71);
  3. cur = coll.find(query);
  4. while(cur.hasNext()){
  5. System.out.println(cur.next());
  6. }
复制代码
11 使用条件查询获取集合
例如,我们想要查询所有i>50的文档:

  1. BasicDBObject query = new BasicDBObject();
  2. query.put("i", new BasicDBObject("$gt", 50));
  3. cur = coll.find(query);
  4. while(cur.hasNext()){
  5. System.out.println(cur.next());
  6. }
复制代码
当然,我们也可以做20 < i <= 30的查询

  1. BasicDBObject query = new BasicDBObject();
  2. query.put("i", new BasicDBObject("$gt", 20).append("$lte", 30));
  3. cur = coll.find(query);
  4. while(cur.hasNext()){
  5. System.out.println(cur.next());
  6. }
复制代码
12 创建索引
MongoDB支持索引,而且很容易在集合上增加索引。要创建索引,只需要指定要加索引的属性,并且指定升序(1)或降序即可(-1)。

  1. coll.createIndex(new BasicDBObject("i", 1));
复制代码
13 获取索引列表



  1. List list = coll.getIndexInfo();
  2. for(DBObject o : list){
  3. System.out.println(o);
  4. }
复制代码
14 MongoDB管理函数
管理函数在com.mongodb.MongoAdmin类中定义。
例A:获取数据库列表

  1. MongoAdmin admin = new MongoAdmin();
  2. for(String s : admin.getDatabaseNames()){
  3. System.out.println(s);
  4. }
复制代码
例B:获取数据库对象

  1. Mongo m = admin.getDB("mydb");
复制代码
例C:删除数据库

  1. admin.dropDatabase("mydb");
复制代码
15 用DBObject存储JAVA对象
MongoDB for JAVA驱动中提供了用于向数据库中存储普通对象的接口DBObject
例如,存在一个需要存储的对象类Tweet

  1. public class Tweet implements DBObject{
  2. /*...*/
  3. }
复制代码
可以使用如下代码:

  1. Tweet myTweet = new Tweet();
  2. myTweet.put("user", userId);
  3. myTweet.put("message", message);
  4. myTweet.put("date", new Date());
  5. collection.insert(myTweet);
复制代码
当一个文档从MongoDB中取出时,它会自动把文档转换成DBObject接口类型,要将它实例化为你的对象,需使用

  1. DBCollection.setObjectClass()。
  2. collection.setObjectClass(Tweet);
  3. Tweet myTweet = (Tweet)collection.findOne();
复制代码
16 JAVA驱动的并发性
JAVA的MongoDB驱动是线程安全的。如果你将它用在WEB服务中,可以创建它的一个单例,并在所有请求中使用它。

然而,如果你需要在一个会话(例如HTTP请求)中保证事务一致性,也许你会希望在这个会话中对驱动使用同一个端口。这仅仅在

请求量非常大的环境中,例如你经常会读取刚写入的数据。
为了这一点,你需要使用如下代码:

  1. Mongo m;
  2. m.restartStart();
  3. // code.........
  4. m.requestDone();
复制代码

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条