索引及集合管理 - MongoDB从入门到删库

索引及集合管理 - MongoDB从入门到删库,第1张

MongoTemplate 提供了一些用于管理索引和集合的方法。这些方法被收集到一个名为 IndexOperations 的帮助接口中。您可以通过调用 indexOps 方法并传入集合名或实体的 javalangClass 来访问这些 *** 作(集合名称来自 class ,或名称,或注释元数据)。

您可以使用 MongoTemplate 类在集合上创建索引,以提高查询性能,还可以使用 IndexDefinition 、 GeoSpatialIndex 和 TextIndexDefinition 类创建标准、地理空间和文本索引。

IndexOperations 接口具有 getIndexInfo 方法,该方法返回 IndexInfo 对象的列表。此列表包含在集合上定义的所有索引。下面的例子定义了Person类上具有age属性的索引:

下面的例子展示了如何创建一个集合:

HelloWorld程序

学习任何程序的第一步,都是编写HelloWorld程序,我们也不例外,看下如何通过Java编写一个HelloWorld的程序。

首先,要通过Java *** 作Mongodb,必须先下载Mongodb的Java驱动程序,可以在这里下载。

新建立一个Java工程,将下载的驱动程序放在库文件路径下,程序代码如下:

package commkyongcore;

import javanetUnknownHostException;

import commongodbBasicDBObject;

import commongodbDB;

import commongodbDBCollection;

import commongodbDBCursor;

import commongodbMongo;

import commongodbMongoException;

/

 Java + MongoDB Hello world Example

 

/

public class App {

    public static void main(String[] args) {

        try {

            //实例化Mongo对象,连接27017端口

            Mongo mongo = new Mongo("localhost", 27017);

                               //连接名为yourdb的数据库,假如数据库不存在的话,mongodb会自动建立

            DB db = mongogetDB("yourdb");

            // Get collection from MongoDB, database named "yourDB"

//从Mongodb中获得名为yourColleection的数据集合,如果该数据集合不存在,Mongodb会为其新建立

            DBCollection collection = dbgetCollection("yourCollection");

    // 使用BasicDBObject对象创建一个mongodb的document,并给予赋值。

            BasicDBObject document = new BasicDBObject();

            documentput("id", 1001);

            documentput("msg", "hello world mongoDB in Java");

            //将新建立的document保存到collection中去

            collectioninsert(document);

            // 创建要查询的document

            BasicDBObject searchQuery = new BasicDBObject();

            searchQueryput("id", 1001);

            // 使用collection的find方法查找document

            DBCursor cursor = collectionfind(searchQuery);

            //循环输出结果

            while (cursorhasNext()) {

            Systemoutprintln(cursornext());

            }

            Systemoutprintln("Done"); 

        } catch (UnknownHostException e) {

            eprintStackTrace();

        } catch (MongoException e) {

            eprintStackTrace();

        }

    }

}

最后,输出的结果为:

{ "_id" : { "$oid" : "4dbe5596dceace565d229dc3"} , 

                "id" : 1001 , "msg" : "hello world mongoDB in Java"}

Done

在上面的例子中,演示了使用Java对Mongodb *** 作的重要方法和步骤,首先通过创建Mongodb对象,传入构造函数的参数是Mongodb的数据库所在地址和端口,然后使用

getDB方法获得要连接的数据库名,使用getCollection获得数据集合的名,然后通过新建立BasicDBObject对象去建立document,最后通过collection的insert方法,将建立的document保存到数据库中去。而collection的find方法,则是用来在数据库中查找document。

从Mongodb中获得collection数据集

在Mongodb中,可以通过如下方法获得数据库中的collection:

DBCollection collection = dbgetCollection("yourCollection");

如果你不知道collection的名称,可以使用dbgetCollectionNames()获得集合,然后再遍历,如下:

DB db = mongogetDB("yourdb");

Set collections = dbgetCollectionNames();

for(String collectionName : collections){

Systemoutprintln(collectionName);

}

完成的一个例子如下:

package commkyongcore;

import javanetUnknownHostException;

import javautilSet;

import commongodbDB;

import commongodbDBCollection;

import commongodbMongo;

import commongodbMongoException;

/

 Java : Get collection from MongoDB

 

/

public class GetCollectionApp {

public static void main(String[] args) {

try {

Mongo mongo = new Mongo("localhost", 27017);

DB db = mongogetDB("yourdb");

Set<String> collections = dbgetCollectionNames();

for (String collectionName : collections) {

Systemoutprintln(collectionName);

}

DBCollection collection = dbgetCollection("yourCollection");

Systemoutprintln(collectiontoString());

Systemoutprintln("Done");

} catch (UnknownHostException e) {

eprintStackTrace();

} catch (MongoException e) {

eprintStackTrace();

}

}

}

Mongodb中如何插入数据

下面,讲解下如何使用4种方式,将JSON数据插入到Mongodb中去。首先我们准备JSON

格式的数据,如下:

 

 {

"database" : "mkyongDB",

"table" : "hosting",

"detail" :

{

records : 99,

index : "vps_index1",

active : "true"

}

}

}

我们希望用不同的方式,通过JAVA代码向Mongodb插入以上格式的JSON数据

第一种方法,是使用BasicDBObject,方法如下代码所示:

BasicDBObject document = new BasicDBObject();

documentput("database", "mkyongDB");

documentput("table", "hosting");

BasicDBObject documentDetail = new BasicDBObject();

documentDetailput("records", "99");

documentDetailput("index", "vps_index1");

documentDetailput("active", "true");

documentput("detail", documentDetail);

collectioninsert(document);

第二种方法是使用BasicDBObjectBuilder对象,如下代码所示:

BasicDBObjectBuilder documentBuilder = BasicDBObjectBuilderstart()

add("database", "mkyongDB")

add("table", "hosting");

BasicDBObjectBuilder documentBuilderDetail = BasicDBObjectBuilderstart()

add("records", "99")

add("index", "vps_index1")

add("active", "true");

documentBuilderadd("detail", documentBuilderDetailget());

collectioninsert(documentBuilderget());

第三种方法是使用Map对象,代码如下:

 

 Map documentMap =new HashMap();

documentMapput("database", "mkyongDB");

documentMapput("table", "hosting");

Map documentMapDetail =new HashMap();

documentMapDetailput("records", "99");

documentMapDetailput("index", "vps_index1");

documentMapDetailput("active", "true");

documentMapput("detail", documentMapDetail);

collectioninsert(new BasicDBObject(documentMap));

第四种方法,也就是最简单的,即直接插入JSON格式数据

String json ="{'database' : 'mkyongDB','table' : 'hosting',"+

"'detail' : {'records' : 99, 'index' : 'vps_index1', 'active' : 'true'}}}";

DBObject dbObject =(DBObject)JSONparse(json);

collectioninsert(dbObject);

这里使用了JSON的parse方法,将解析后的JSON字符串转变为DBObject对象后再直接插入到collection中去。

完整的代码如下所示:

packagecommkyongcore;

importjavanetUnknownHostException;

importjavautilHashMap;

importjavautilMap;

importcommongodbBasicDBObject;

importcommongodbBasicDBObjectBuilder;

importcommongodbDB;

importcommongodbDBCollection;

importcommongodbDBCursor;

importcommongodbDBObject;

importcommongodbMongo;

importcommongodbMongoException;

importcommongodbutilJSON;

/

Java MongoDB : Insert a Document

/

publicclass InsertDocumentApp {

publicstaticvoid main(String[] args){

try{

Mongo mongo =new Mongo("localhost", 27017);

DB db = mongogetDB("yourdb");

// get a single collection

DBCollection collection = dbgetCollection("dummyColl");

// BasicDBObject example

Systemoutprintln("BasicDBObject example");

BasicDBObject document =new BasicDBObject();

documentput("database", "mkyongDB");

documentput("table", "hosting");

BasicDBObject documentDetail =new BasicDBObject();

documentDetailput("records", "99");

documentDetailput("index", "vps_index1");

documentDetailput("active", "true");

documentput("detail", documentDetail);

collectioninsert(document);

DBCursor cursorDoc = collectionfind();

while(cursorDochasNext()){

Systemoutprintln(cursorDocnext());

}

collectionremove(new BasicDBObject());

// BasicDBObjectBuilder example

Systemoutprintln("BasicDBObjectBuilder example");

BasicDBObjectBuilder documentBuilder = BasicDBObjectBuilderstart()

add("database", "mkyongDB")

add("table", "hosting");

BasicDBObjectBuilder documentBuilderDetail = BasicDBObjectBuilderstart()

add("records", "99")

add("index", "vps_index1")

add("active", "true");

documentBuilderadd("detail", documentBuilderDetailget());

collectioninsert(documentBuilderget());

DBCursor cursorDocBuilder = collectionfind();

while(cursorDocBuilderhasNext()){

Systemoutprintln(cursorDocBuildernext());

}

collectionremove(new BasicDBObject());

// Map example

Systemoutprintln("Map example");

Map documentMap =new HashMap();

documentMapput("database", "mkyongDB");

documentMapput("table", "hosting");

Map documentMapDetail =new HashMap();

documentMapDetailput("records", "99");

documentMapDetailput("index", "vps_index1");

documentMapDetailput("active", "true");

documentMapput("detail", documentMapDetail);

collectioninsert(new BasicDBObject(documentMap));

DBCursor cursorDocMap = collectionfind();

while(cursorDocMaphasNext()){

Systemoutprintln(cursorDocMapnext());

}

collectionremove(new BasicDBObject());

// JSON parse example

Systemoutprintln("JSON parse example");

String json ="{'database' : 'mkyongDB','table' : 'hosting',"+

"'detail' : {'records' : 99, 'index' : 'vps_index1', 'active' : 'true'}}}";

DBObject dbObject =(DBObject)JSONparse(json);

collectioninsert(dbObject);

DBCursor cursorDocJSON = collectionfind();

while(cursorDocJSONhasNext()){

Systemoutprintln(cursorDocJSONnext());

}

collectionremove(new BasicDBObject());

}catch(UnknownHostException e){

eprintStackTrace();

}catch(MongoException e){

eprintStackTrace();

}

}

}

 

在mongodb 50 版本新增的功能,它有效地存储了一段时期内的测量序列。时间序列数据是随着时间收集的任何类型的数据,并由一个或多个不变参数唯一标识, 这些不变参数通常又称为是数据源的元数据

示例:

与普通集合相比,将时序数据存储在时序集合中提高了查询效率,减少了时序数据和次级索引(secondary index)的磁盘存储空间。

时间序列集合的特性类似于普通集合。您可以像往常一样插入和查询数据。 MongoDB 将时间序列集合视为内部集合的可写非物化视图,在插入时自动将时间序列数据组织成优化的存储格式。 当您查询时间序列集合时,您每次测量 *** 作一个文档。对时间序列集合的查询利用优化的内部存储格式并更快地返回结果。

创建时间序列集合时,可以使用 expireAfterSeconds 参数设置自动删除过期的文档:

过期阈值是 timeField 字段值加上设定的过期秒数

例如 weather24h集合中有如下的文档

那该文档将在ISODate("2021-05-18T10:00:00000Z") + 86400s 的时间过期

在上一篇 mongodb Aggregation聚合 *** 作之$lookup 中详细介绍了mongodb聚合 *** 作中的$lookup使用以及参数细节。本篇将开始介绍Aggregation聚合 *** 作中的$collStats *** 作。

说明:

返回关于集合或视图的统计信息。请注意:$collStats必须是聚合管道的第一个阶段,否则管道将返回错误。

语法:

{

  $collStats:

    {

      latencyStats: { histograms: <boolean> },

      storageStats: {},

      count: {}

    }

}

参数讲解:

latencyStats:将延迟统计信息添加到返回文档中。

latencyStatshistograms:如果为真,则向latencyStats中嵌入的文档添加延迟直方图信息。

storageStats:将存储统计信息添加到返回文档中。

count:将集合中的文档总数添加到返回文档中,计数基于集合的元数据,该元数据为分片集群提供了快速但有时不准确的计数。

注意点:

对于副本集中的集合或集群中的非分片集合,$collStats输出单个文档。对于分片集合,$collStats为每个分片输出一个文档。输出文档包括以下字段

ns:请求的集合或视图的名称空间。

shard:输出文档对应的切分的名称。仅当$collStats在分片集群上运行时才出现。分片集合和非分片集合都将生成此字段。

host:生成输出文档的mongod进程的主机名和端口。

localTime:MongoDB服务器上的当前时间,自Unix时代以来以UTC毫秒表示。

latencyStats:与集合或视图的请求延迟相关的统计信息集合。有关此文档的详细信息,请参阅latencyStats文档。仅在指定latencyStats:{}选项时出现。

storageStats:与集合的存储引擎相关的统计信息集合。有关此文档的详细信息,请参阅storageStats文档。仅在指定storageStats:{}选项时出现。如果应用于视图,则返回错误。

count:集合中文档的总数。这个数据也可以在storageStatscount中获得,计数基于集合的元数据,该元数据为分片集群提供了快速但有时不准确的计数。只在指定count:{}选项时出现。如果应用于视图,则返回错误。

dbquestionaggregate( [ { $collStats: { storageStats: {} } } ] )

对数据进行聚合 *** 作,然后将计算之后的数据返回。聚合 *** 作将多个文档的值组合在依赖,并且可以对分组数据执行各种 *** 作返回单个结果。

MongoDB提供三种方式来执行聚合 *** 作:aggregation pipeline、map-reduce function、single purpose aggregation methods。

MongoDB 聚合 *** 作是在数据处理管道的逻辑上建模的。documents可以进入一个用于处理docuemnt然后返回聚合值的多阶段管道。

底层的管道提供了filters(类似于查询的 *** 作)和document transformations(修改document的输出形式) *** 作。

其他管道 *** 作为document指定具体的属性或者多个属性进行分组和排序,以及用array内容的聚合工具一样。管道的阶段可以使用运算符执行任务。

管道使用MongoDB自带的本地 *** 作来执行聚合 *** 作更高效,管道是MongoDB执行聚合 *** 作的首先。

聚合管道可以 *** 作分片collection。聚合管道可以通过使用索引来提高性能。聚合管道内部会进行优化阶段。

可以使用dbcollectionaggregate()的explain参数看到执行计划。

聚合管道来决定需要返回的字段。如果使用只需要的字段,这样可以减少数据量。

addFields + match放入到 addFields之前(如果是 project / $addFields的结果,就不能移动),减少数据量。

match: 先执行$match来减少数据量,然后在执行排序 *** 作。

match: 如果在前面添加$match *** 作,可以使用索引来减少数据 *** 作。

skip(在32开始可以使用):将 project *** 作之前,可以减少数据量。

通常情况下,在重新排序优化之后才会发生阶段合并。

limit:如果不能减少数据量,不会将这两个阶段合并。否则先进行排序,然后获取指定的数量,放入内存。如果在中间含有$skip *** 作,将其放入最后。

在数据量超过内存限制,这个 *** 作需要设置 allowDiskUse=true。

从MongoDB36开始,删除了aggregate的选项,将结果作为一条数据的返回。

aggregate可以返回cursor或者数据结果集。在返回的结果中,每个document的大小不能超过16M(这个限制只针对返回的document)。

documents有可能会超过这个限制,dbcollectionaggregate()默认返回cursor。

从MongoDB26开始,管道阶段的RAM限制为100M。如果超过限制,出错。如果为了处理大量的数据集,使用allowDiskUse选项开启管道阶段的聚合 *** 作将数据写入到临时文件。

从MongoDB34之后, graphLookup *** 作会忽略这个选项。如果其他阶段有aggregate() *** 作,allowDiskUse=true将会影响这些阶段。

从MongoDB32开始,如果按照分片来匹配值,只会在这个分片内进行计算。

聚合 *** 作在多个分片上执行 *** 作,如果没有指定主分片,这些 *** 作会被路由到其他分片上,来减少主分片的负载。

lookup阶段需要在主分片上执行查询。

将聚合管道拆分为两部分,这是为了在分片上执行优化。

*** 作可以 参考实例

MapReduce可以在分片上执行 *** 作,分片集合可以作为输入或者输出。

使用分片集合作为MapReduce输入源,mongos将作业并行派发到各个分片。mongos会等待所有的作业完成。

如果MapReduce的out字段有分片值,MongoDB使用_id字段作为分片的依据。

作为一个分片集合输出:

在 *** 作的过程中,mapreduce有很多锁:

相关 练习教程

MongoDB 50标志着一个新的发布周期的到来,以更快地交付新特性给到用户。版本化API与在线重新分片相结合,使用户不必担心未来的数据库升级以及业务变化问题;本地原生时间序列数据平台也使MongoDB能支持更广泛的工作负载和业务场景;新的MongoDB Shell能够提升用户体验等均为MongoDB 50的功能。本文主要介绍MongoDB 50的新特性。

MongoDB 50通过原生支持整个时间序列数据的生命周期(从采集、存储、查询、实时分析和可视化,到在线归档或随着数据老化自动失效),使构建和运行时间序列应用程序的速度更快、成本更低。随着MongoDB 50的发布,MongoDB扩展了通用的应用数据平台,使开发能够更容易地处理时间序列数据,进一步扩展其在物联网、金融分析、物流等方面的应用场景。

MongoDB的时间序列集合以高度优化和压缩的格式自动存储时间序列数据,减少了存储大小和I/O,以实现更好的性能和更大的规模。同时也缩短了开发周期,使您能够快速建立一个针对时间序列应用的性能和分析需求而调优的模型。

创建时间序列数据集合的命令示例:

MongoDB可以无缝地调整采集频率,并根据动态生成的时间分区自动处理无序的测量值。最新发布的MongoDB Connector for Apache Kafka实现了在本地支持时间序列,您可以直接从Kafka主题消息中自动创建时间序列集合,使您在收集数据的同时根据需要对数据进行处理和聚合,然后写入到MongoDB的时间序列集合。

时间序列集合自动创建一个按时间排序的数据聚集索引,降低查询数据的延迟。MongoDB查询API还扩展了窗口函数,您可以运行分析性查询(例如移动平均数和累积总和)。在关系型数据库系统中,这些通常被称为SQL分析函数,并支持以行为单位定义的窗口(即三行移动平均线)。MongoDB更进一步,还增加了指数移动平均线、导数和积分等强大的时间序列函数,支持您以时间为单位定义窗口(例如15分钟的移动平均线)。窗口函数可用于查询MongoDB的时间序列和常规集合,为多种应用类型提供了新的分析方式。另外,MongoDB 50也提供了新的时间运算符,包括$dateAdd、$dateSubstract、$dateDiff和$dateTrunc,使您可以通过自定义的时间窗口对数据进行汇总和查询。

您可以将MongoDB的时间序列数据与企业的其他数据相结合。时间序列集合可以与同一个数据库中的常规MongoDB集合放在一起,您不必选择一个专门的时间序列数据库(它不能为任何其他类型的应用提供服务),也不需要复杂的集成来混合时间序列和其他数据。MongoDB通过提供一个统一的平台,让您建立高性能和高效的时间序列应用的同时,也为其他用例或工作负载提供支持,从而消除了整合和运行多个不同数据库的成本和复杂性。

从MongoDB 50开始, Write Concern 默认级别为majority,仅当写入 *** 作被应用到Primary节点(主节点)且被持久化到大多数副本节点的日志中的时候,才会提交并返回成功,“开箱即用”地提供了更强的数据可靠性保障。

说明 Write Concern 是完全可调的,您可以自定义配置 Write Concern ,以平衡应用程序对数据库性能和数据持久性的要求。

默认情况下,一个客户端连接对应后端MongoDB服务器上的一个线程( netserviceExecutor 配置为synchronous)。创建、切换和销毁线程都是消耗较大的 *** 作,当连接数过多时,线程会占用MongoDB服务器较多的资源。

连接数较多或创建连接失控的情况称为“连接风暴”,产生该情况的原因可能是多方面的,且经常是在服务已经受到影响的情况下发生。

针对这些情况,MongoDB 50采取了以下措施:

以上措施,加上之前版本在mongos查询路由层的改进,进一步提升了MongoDB承受高并发负载的能力。

长时间运行的快照查询(Long-Running Snapshot Queries)增加了应用程序的通用性和d性。您可以通过该功能运行默认时间为5分钟的查询(或将其调整为自定义持续时间),同时保持与实时事务性数据库一致的快照隔离,也可以在Secondary节点(从节点)上进行快照查询,从而在单个集群中运行不同的工作负载,并将其扩展到不同的分片上。

MongoDB通过底层存储引擎中一个名为Durable history的项目实现了长期运行的快照查询,该项目早在MongoDB 44中就已实现。Durable history将存储自查询开始以来所有变化的字段值的快照。通过使用Durable history,查询可以保持快照隔离,即使在数据发生变化的情况下,Durable history也有助于降低存储引擎的缓存压力,使得业务可以在高写入负载的场景下实现更高的查询吞吐量。

为了提供更好的用户体验,MongoDB 50从头开始重新设计了MongoDB Shell(mongosh),以提供一个更现代化的命令行体验,以及增强可用性的功能和强大的脚本环境。新版MongoDB Shell已经成为MongoDB平台的默认shell。新版MongoDB Shell引入了语法高亮、智能自动完成、上下文帮助和有用的错误信息,为您创造一个直观、互动的体验。

随着新的PyMongoArrow API的发布,您可以在MongoDB上使用Python运行复杂的分析和机器学习。PyMongoArrow可以快速将简单的MongoDB查询结果转换为流行的数据格式(例如Pandas数据框架和NumPy数组),帮助您简化数据科学工作流程。

Schema验证(模式验证)是对MongoDB进行数据应用管理控制的一种方式。MongoDB 50中,模式验证变得更加简单和友好,当 *** 作验证失败时都会产生描述性的错误信息,帮助您了解不符合集合验证器的验证规则的文档及原因,以快速识别和纠正影响验证规则的错误代码。

MongoDB 50支持将正在进行中的索引创建任务在节点重新启动后自动会恢复至原来的位置,减少计划中维护动作对业务的影响。例如:重新启动或升级数据库节点时,您不需要担心当前正在进行的大集合索引创建任务失效。

由于MongoDB支持很多版本和平台,每个发布版本都需在20多个MongoDB支持的平台上进行验证,验证工作量大,降低了MongoDB新功能的交付速度,所以从MongoDB 50开始,MongoDB发布的版本将分为Marjor Release(大版本)和Rapid Releases(快速发布版本),其中Rapid Releases作为开发版本提供下载和测试体验,但不建议用在生产环境。

以上就是关于索引及集合管理 - MongoDB从入门到删库全部的内容,包括:索引及集合管理 - MongoDB从入门到删库、如何用Java *** 作MongoDB、mongodb - 时间序列集合(time series collection)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9514343.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存