zoukankan      html  css  js  c++  java
  • MongoDB 学习

     一、什么是NoSQL?

      NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。

      NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

      NoSQL的优点/缺点:

        优点:高可扩展性、分布式计算、低成本、架构的灵活性,半结构化数据、没有复杂的关系

        缺点:没有标准化、有限的查询功能(到目前为止)、最终一致是不直观的程序

      NoSQL数据库分类:

    类型 部分代表 特点
    列存储

    Hbase

    Cassandra

    Hypertable

    顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。
    文档存储

    MongoDB

    CouchDB

    文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。
    key-value存储

    MemcacheDB

    Redis

    可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能)
    图存储

    Neo4J

    FlockDB

    图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。
    对象存储

    db4o

    Versant

    通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据
    xml数据库

    Berkeley DB XML

    BaseX

     高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath

    二、什么是MongoDB?

      官网:https://www.mongodb.com/2

      菜鸟教程:https://www.runoob.com/mongodb/mongodb-tutorial.html

      MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

      MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

      MongoDB 将数据存储为一个文档,数据结构由键值(key-value)键值对组成。MongoDB文档类似于JSON对象。字段值可以包含其他文档,数组及文档数组。

      

      1、MongoDB概念/与SQL区别

    SQL术语/概念MongoDB术语/概念解释/说明
    database database 数据库
    table collection 数据库表/集合
    row document 数据记录行/文档
    column field 数据字段/域
    index index 索引
    table joins   表连接,MongoDB不支持
    primary key primary key 主键,MongoDB自动将_id字段设置为主键

      示例:

      

      2、MongoDB连接

      mongodb://[username:password@]host1[:port1] [,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

        mongodb:// 这是固定的格式,必须要指定。

        username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登录这个数据库

        host1 必须的指定至少一个host, host1 是这个URI唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。

        portX 可选的指定端口,如果不填,默认为27017

        /database 如果指定username:password@,连接并验证登录指定数据库。若不指定,默认打开 test 数据库。

        ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开

      

        如:

          使用用户名fred,密码foobar登录localhost的baz数据库:mongodb://fred:foobar@localhost/baz

          连接 replica set 三台服务器 (端口 27017, 27018, 和27019):mongodb://localhost,localhost:27018,localhost:27019

        

      3、常用的命令:

        1、show dbs :显示所有数据库的列表

        2、use [db名称]:指定一个数据库、如果没有则会创建此数据库

        3、db:显示当前数据库对象或集合

        4、show collections:显示当前库下所有的集合

        5、db.dropshiyongDatabase():先使用use命令切换到要删除的库下,然后使用此命令删除当前库

        6、db.collection.drop():删除集合

        7、db.createCollection(name, options):创建集合,options可选参数(具体参考文档)。

          注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

        8、db.COLLECTION_NAME.insert(document) :向集合中插入文档(一条记录),如果集合mycol2不存在,会自动创建

          9、db.col.remove({'key1':'MongoDB 教程'}):删除

      4、MongoDB查询文档

        db.collection.find(query, projection)

          query :可选,使用查询操作符指定查询条件  

          projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)

          db.col.find().pretty(): 使用pretty方法,使结果易读

      

          1)MongoDB与RDBMS WHERE语句比较

    操作格式范例RDBMS中的类似语句
    等于 {<key>:<value>} db.col.find({"key1":"value1"}).pretty() where key1 = 'value1'
    小于 {<key>:{$lt:<value>}} db.col.find({"key1":{$lt:50}}).pretty() where key1 < 50
    小于或等于 {<key>:{$lte:<value>}} db.col.find({"key1":{$lte:50}}).pretty() where key1 <= 50
    大于 {<key>:{$gt:<value>}} db.col.find({"key1":{$gt:50}}).pretty() where key1 > 50
    大于或等于 {<key>:{$gte:<value>}} db.col.find({"key1":{$gte:50}}).pretty() where key1 >= 50
    不等于 {<key>:{$ne:<value>}} db.col.find({"key1":{$ne:50}}).pretty() where key1 != 50

          2)AND 条件

           MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。语法格式如下:

            >db.col.find({key1:value1, key2:value2}).pretty()

          3)OR 条件

          OR 条件语句使用了关键字 $or,语法格式如下:

            >db.col.find(
               {
                  $or: [
                     {key1: value1}, {key2:value2}
                  ]
               }
            ).pretty()
          表示查询键为key1,值为value1或键为key2,值为value2的文档

          4)AND 和 OR 联合使用

            >db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()

          5)排序 ,使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。

            >db.COLLECTION_NAME.find().sort({KEY:1})

          

      5、索引

        索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构

        1) 创建索引:createIndex()

            注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名。

          >db.collection.createIndex(keys, options)

            key为要创建索引的字段,1表示按升序创建索引,-1表示按降序创建索引。如:db.col.createIndex({"title":1,"description":-1}),表示创建title和description两个字段的索引,一个升序,一个降序

            options 选项参考文档

      6、与Java整合

        1)引入依赖

    <dependencies>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.5.0</version>
        </dependency>
    </dependencies>

        2)建立连接

    MongoClientURI connectionString = new MongoClientURI("mongodb://localhost:27017,localhost:27018,localhost:27019");
    // MongoClient实例表示与数据库的连接池。即使有多个线程,您也只需要一个MongoClient类的实例。
    // 所以我们可以在给定的数据库集群创建一个MongoClient实例,并在整个应用程序中使用它
    MongoClient mongoClient = new MongoClient(connectionString);
    // 连接具体数据库
    MongoDatabase database = mongoClient.getDatabase("mydb");

        3)增删改查操作

    // 获取某个集合
    MongoCollection<Document> collection = database.getCollection("test");
    
    // 创建一条文档(JSON对象字符串)
    Document doc = new Document("name", "MongoDB")
                   .append("type", "database")
                   .append("count", 1)
                   .append("info", new Document("x", 203).append("y", 102));
    
    // 插入文档
    collection.insertOne(doc);
    
    // 批量插入
    List<Document> documents = new ArrayList<Document>();
    collection.insertMany(documents);
    
    // 获取集合下文档数量
    collection.count()
    
    // 查询集合中的第一条文档
    Document myDoc = collection.find().first();
    
    // 查询集合中的所有文档
    MongoCursor<Document> cursor = collection.find().iterator();
    try {
        while (cursor.hasNext()) {
            System.out.println(cursor.next().toJson());
        }
    } finally {
        cursor.close();
    }
    
    //  使用filter查询符合条件的记录,如查询field为age,值为26的文档记录
    Document myDoc = collection.find(eq("age", 26)).first();
    
    // 查询符合条件(50<i<100)的多条文档,并遍历
    // now use a range query to get a larger subset
    Block<Document> printBlock = new Block<Document>() {
         @Override
         public void apply(final Document document) {
             System.out.println(document.toJson());
         }
    };
    collection.find(and(gt("i", 50), lte("i", 100))).forEach(printBlock);
    
    // 对i字段进行降序 
    Document myDoc = collection.find(exists("i")).sort(descending("i")).first();
    
    // 查询到的文档排除掉 _id 字段    
    Document myDoc = collection.find().projection(excludeId()).first();
    
    // 更新符合过滤器的最多一个文档,使用updateOne。如更新i字段等于10的第一条符合记录的文档,并将i更新为110
    collection.updateOne(eq("i", 10), new Document("$set", new Document("i", 110)));
    
    // 更新符合过滤器的所有文档,使用updateMany。如更新字段i为10的所有所有文档,返回的UpdateResult 包含更新的文档数
    UpdateResult updateResult = collection.updateMany(lt("i", 100),
              new Document("$inc", new Document("i", 100)));
    
    // 删除文档
    collection.deleteOne(eq("i", 110));
    DeleteResult deleteResult = collection.deleteMany(gte("i", 100));
    View Code

     附录:

      Mongo连接工具类:

    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientURI;
    import com.mongodb.client.MongoDatabase;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.core.io.support.PropertiesLoaderUtils;
    
    import java.io.IOException;
    import java.util.Properties;
    
    /**
     * @author yangyongjie
     * @date 2021/1/25
     * @desc
     */
    public enum MongoUtil {
    
        /**
         * 定义一个枚举元素,代表此类的一个实例
         */
        INSTANCE;
    
        private static final Logger LOGGER = LoggerFactory.getLogger(MongoUtil.class);
    
        private MongoClient mongoClient;
    
        /**
         * 重写枚举类的构造方法,枚举类经编译后会在将其放在静态代码块中,在类加载的初始化阶段被调用
         */
        private MongoUtil() {
            Properties properties = null;
            try {
                properties = PropertiesLoaderUtils.loadAllProperties("application.properties");
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (properties != null) {
                MongoClientURI connectionString = new MongoClientURI(properties.getProperty("mongo.url"));
                // MongoClient实例表示与数据库的连接池。即使有多个线程,您也只需要一个MongoClient类的实例。
                // 所以我们可以在给定的数据库集群创建一个MongoClient实例,并在整个应用程序中使用它
                this.mongoClient = new MongoClient(connectionString);
            }
        }
    
        /*private static MongoClient mongoClient;
    
        static {
            Properties properties = new Properties();
            try {
                InputStream is = ClassLoader.getSystemResourceAsStream("application.properties");
                properties.load(is);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (properties != null) {
                MongoClientURI connectionString = new MongoClientURI(properties.getProperty("mongo.url"));
                // MongoClient实例表示与数据库的连接池。即使有多个线程,您也只需要一个MongoClient类的实例。
                // 所以我们可以在给定的数据库集群创建一个MongoClient实例,并在整个应用程序中使用它
                mongoClient = new MongoClient(connectionString);
            }
        }*/
        
        public MongoDatabase getDB(String dbName) {
            if (dbName != null && !"".equals(dbName)) {
                MongoDatabase database = mongoClient.getDatabase(dbName);
                return database;
            }
            return null;
        }
    
    }
    View Code

      用法:MongoUtil.INSTANCE.getMiShopDB("db") 

    END.

      
  • 相关阅读:
    javascript block
    What is the difference between a function expression vs declaration in JavaScript?
    Clean Cache Struts2 Interceptor Tutorial
    第四节,目标检测---YOLO系列
    第三节,目标检测---R-CNN网络系列
    第二节:解决过拟合与梯度下降优化
    第一节,直观理解卷积神经网络
    第六节:深度学习的模型训练技巧——优化卷积核,多通道卷积,批量归一化
    第五节,损失函数:MSE和交叉熵
    第四节:tensorflow图的基本操作
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/14200740.html
Copyright © 2011-2022 走看看