MongoDB特殊索引和集合类型

MongoDB 中的一些特殊的索引和集合类型,包括:

  • 用于类队列数据的固定集合(capped collection);
  • 用于缓存的 TTL 索引;
  • 用于简单字符串搜索的全文本索引;
  • 用于二维平面和球体空间的地理空间索引;
  • 用于存储大文件的 GridFS。

地理空间索引

MongoDB 有两种类型的地理空间索引:2dsphere 和 2d。2dsphere 索引可以与基于 WGS84 基准的地球球面几何模型一起使用。这个基准将地球表面模拟成一个扁圆球体,这意味着在两极会比较扁。因此,使用 2dsphere 索引的距离计算考虑到了地球的形状,提供了比 2d 索引更准确的距离处理,比如计算两个城市之间的距离。在存储二维平面上的点时使用 2d 索引。

2dsphere 允许以 GeoJSON 格式指定点、线和多边形这些几何图形。一个点由一个二元数组给出,表示 [ 经度,纬度 ]([longitude,latitude]):
{
  “name”:“shenzhen”,
   “loc”:{
    “type”:“Point”,
    “coordinates”: [[0,1],[0,2],[1,2]]
 }
}
线可以用一个由点组成的数组来表示:
{
  “name”:“shenzhen”,
   “loc”:{
    “type”:“LineString”,
    “coordinates”: [[0,1],[0,2],[1,2]]
 }
}
多边形的表示方式与线(由点组成的数组)一样,但是 “type” 不同:
{
  “name”:“shenzhen”,
   “loc”:{
    “type”:“Polygon”,
    “coordinates”: [[0,1],[0,2],[1,2],[0,1]]
 }
}
以上例子中“loc”字段可以时自定义名称,内嵌对象的名称是固定的,不能改变

创建地理空间索引:
db.test.createIndex({“loc”:“2dsphere”})

地理空间查询的类型

可以使用 3 种类型的地理空间查询:交集(intersection)、包含(within)和接近(nearness)。查询时,需要将想查找的内容指定为 {“$geometry” :geoJsonDesc} 格式的 GeoJSON 对象。
1、可以使用 “$geoIntersects” 运算符找出与查询位置相交的文档:
>var shenzhen={
  “type”:“Polygon”,
  “coordinates”:[
    [
    [-73.97678686,40.76253627373],
    [-73.97678686,40.76253627374],
    [-73.97678686,40.76253627375],
    [-73.97678686,40.76253627376],
    [-73.97678686,40.76253627377],
    [-73.97678686,40.76253627378],
    [-73.97678686,40.76253627379]
    ]
  ]
}
>db.test.find({“loc”: {“$geoIntersects”:{“$geometry”:shenzhen} } })
这样就可以找到所有与shenzhen有交集的包含点线和多边形的文档。
2、使用 “$geoWithin” 来查询完全包含在某个区域中的文档。例如,shenzhen中有哪些餐馆?
>db.test.find(“loc”:{“$geoWithin”:{“$geometry”:shenzhen}})
不同于第一个查询,这次不会返回那些只是经过 shenzhen(比如街道)或者部分重叠(比如用于表示guangzhou的多边形)的文档。
3、可以使用 “$geoNear” 来查询附近的位置:
>db.test.find({“loc”: {“$geoNear”:{“$geometry”:shenzhen}}})

使用地理空间索引

MongoDB 的地理空间索引允许你高效地对包含地理空间形状和点的集合执行空间查询。
假设我们正在设计一个移动应用程序来帮助用户找到纽约市的餐馆。此应用程序必须:

  • 确定用户当前所在的街区;
  • 显示那个街区的餐馆数量;
  • 找出指定距离内的餐馆。
  • 我们将使用一个 2dsphere 索引来查询球面几何的数据。
    1、地理空间查询可以使用球面或二维(平面)几何图形,这取决于查询和所使用的索引类型。
    在这里插入图片描述
    注意,2d 索引既支持平面几何图形,也支持球面上仅涉及距离的计算(比如,使用 $nearSphere)。然而,在进行球面几何图形的查询时使用 2dsphere 索引会更加高效和准确。

还有一点需要注意,$geoNear 是一个聚合运算符。除了 n e a r 查 询 操 作 , near 查询操作, neargeoNear 聚合运算符和特殊命令 geoNear 也可以查询附近的位置。请记住,$near 查询运算符不适用于使用分片

使用 geoNear 命令和 $geoNear 聚合运算符时,集合中最多只能有一个2dsphere 索引和 2d 索引,而地理空间查询运算符(比如 $near 和$geoWithin)允许集合有多个地理空间索引。

geoNear 命令和 $geoNear 聚合运算符的地理空间索引存在限制,因为 geoNear命令和 $geoNear 语法都不包含位置字段。因此,系统无法明确地在多个 2d 索引或 2dsphere 索引之间进行选择。

地理空间查询运算符则没有这样的限制,这些运算符使用了位置字段,因此消除了歧义。

由于将三维球体(如地球)投影到平面上的性质,当在地图上可视化时,球面几何图形会出现变形。

如果用户的移动设备可以为其提供比较准确的位置,那么用 $geoIntersects 找到用户当前所在的街区就很简单了。
假设用户所在的经度为 -73.934 146 57,纬度为 40.823 029 03。要找到当前的街区,可以使用 GeoJSON 格式的特殊字段 $geometry 来指定一个点:
>db.test.findOne({“loc”:{“$geoIntersects”:{“$geometry”:{type:“Point”,coordinates:[-73.934 146 57,40.823 029 03]}}}})

要找到距离某个点指定范围内的目标,可以结合使用 “$geoWithin” 和"$centerSphere" 来返回无序的结果,或者结合使用 “\$nearSphere” 和"$maxDistance" 来返回按距离排序的结果。

要在一个圆形区域内找到目标,可以结合使用 “$geoWithin” 和"$centerSphere"。“$centerSphere” 是 MongoDB 特有的语法,通过指定圆心和以弧度表示的半径来标识一个圆形区域。“$geoWithin” 不会以任何特定的顺序返回文档,因此它有可能会先返回距离最远的文档。比如返回距离用户5英里的目标
>db.test.find({“loc”: {“$geoWithin”:{“$centerSphere”:[-73.3242343,40.342343432],5/3963.2}}})

应用程序可以在没有地理空间索引的情况下使用 “$centerSphere”。然而,有地理空间索引比没有地理空间索引在查询速度上要快得多。2dsphere 和 2d 两种地理空间索引都支持 “$centerSphere”。

也可以使用 “$nearSphere” 并指定一个以米为单位的 “$maxDistance”。这样做会返回距离用户 5 英里内的所有餐馆,并按由近到远的顺序进行排序。
>var meters_per_mile=1609.34
>db.test.find({“loc”:{“$nearSphere”:{“$geometry”:{“type”:“Point”,“coordinates”:[-73.3242343,40.342343432]}}}})
11 英里 = 1.609 344 千米。

复合地理空间索引

>db.test.createIndex({“name”:1,“loc”:“2dsphere”})
其他“普通”的索引字段可以放在 “2dsphere” 字段之前或之后,这取决于是希望先使用普通索引字段进行过滤还是先使用位置进行过滤。应该将更有选择性(可以过滤掉更多结果)的字段放在前面。

2d索引

对于非球面地图(电子游戏地图、时间序列数据等),可以使用 2d 索引代替2dsphere 索引:
>db.test.createIndex({“loc”:“2d”})
2d 索引适用于完全平坦的表面,而不是球体表面。因此,2d 索引不应该用于球体表面,除非你不介意在极点周围产生明显的扭曲变形。

如果想存储 GeoJSON 数据,就不要使用 2d 索引,因为它们只能对点进行索引。可以存储一个由点组成的数组,但是它只会被精确地保存为由点组成的数组,而不是一条直线。特别是对于 “ g e o W i t h i n " 查 询 来 说 , 这 是 一 个 重 要 的 区 别 。 如 果 将 一 条 街 道 存 储 为 由 点 组 成 的 数 组 , 那 么 如 果 其 中 某 个 点 位 于 给 定 的 形 状 内 , 这 个 文 档 就 会 与 " geoWithin" 查询来说,这是一个重要的区别。如果将一条街道存储为由点组成的数组,那么如果其中某个点位于给定的形状内,这个文档就会与 " geoWithin""geoWithin” 相匹配。然而,由这些点组成的线可能并不完全包含在这个形状内。

默认情况下,2d 索引会假设取值范围为 -180 到 180。如果希望对边界大小进行调整,则可以指定最小值和最大值作为 createIndex 的选项:
>db.test.createIndex({“loc”:“2d”},{“min”:-1000,“max”:1000})
这会针对一个 2000×2000 的正方形创建空间索引。

2d 索引支持 “$geoWithin”、“\ n e a r S p h e r e " 和 " nearSphere" 和 " nearSphere""near” 查询选择器。应该使用"$geoWithin" 查询在平面上定义的形状内的点。“$geoWithin” 可以查询矩形、多边形、圆形或球体内的所有点,它使用 “$geometry” 运算符来指定 GeoJSON 对象。返回到网格索引如下:
>db.test.createIndex({“loc”:2d})

可以使用如下语句对左下角定义为 [10, 10]、右上角定义为 [100, 100] 的矩形内的文档进行查询:
>db.test.find(“loc”:{“$geoWithin”:{“$box”:[[10,10],[100,100]]}})
$box 会接受一个双元素数组:第一个元素指定左下角的坐标,第二个元素指定右上角的坐标。

要查询位于圆心 [-17, 20.5]、半径为 25 的圆形内的文档,可以使用以下命令:
>db.test.find({“loc”:{“\geoWithin”:{“$center”:[[-17,20.5],25]}}})

以下查询会返回由 [0, 0]、[3, 6] 和 [6, 0] 坐标所定义的多边形内的所有文档:
>db.test.find({“loc”:{“$geowith”:{“$polygon”:[[0,0],[3,6],[6,0]]}}})
将多边形指定为一个由点组成的数组。列表中的最后一个点将“连接”到第一个点以形成多边形。这个例子会查询出包含给定三角形内点的所有文档。

由于历史遗留原因,MongoDB 还支持在平面 2d 索引上进行球面查询。通常来说,球面计算应该使用 2dsphere 索引,不过,要查询球体内的历史遗留坐标对,需要结合使用 “$geoWithin” 和 “$centerSphere” 运算符。指定一个数组,其中包括:
圆心的网格坐标;
以弧度为单位的圆半径。
例如:
>db.test.find({“loc”:{“$geoWithin”:{“$centerSphere”:[[88,30],10/3693.2]}}})

要查询附近的点,需要使用 “$near”。临近查询会返回距离给定点最近的坐标对的文档,并按照距离对结果进行排序。以下查询会找出 test 集合中所有的文档,并按照与点 [20, 21] 的距离进行排序:
>db.test.find({“loc”:{“$near”:[20,21]}})
如果没有指定,则默认限制最多返回 100 个文档。如果不需要那么多结果,则应该设置一个限制来节省服务器端资源。例如,下面的代码会返回最接近 [20, 21] 的10 个文档。
>db.test.find({“loc”:{“$near”:[20,21]}}).limit(10)

全文搜索索引

MongoDB 中的 text 索引支持全文搜索,text 索引可以快速搜索文本并提供对一些常见搜索引擎需求(比如适合于语言的标记化、停止单词和词干提取)的支持。

text 索引需要一定数量的与被索引字段中单词成比例的键。因此,创建 text 索引可能会消耗大量的系统资源。应该在确定不会对用户的应用程序性能产生负面影响的情况下创建这样的索引,或者如果可能的话,在后台创建索引。与所有其他索引一样,为了确保良好的性能,还应该注意所创建的 text 索引要能被 RAM 所容纳。创建索引的同时要尽量减少对应用程序的影响。

text 索引需要一定数量的与被索引字段中单词成比例的键。因此,创建 text 索引可能会消耗大量的系统资源。应该在确定不会对用户的应用程序性能产生负面影响的情况下创建这样的索引,或者如果可能的话,在后台创建索引。与所有其他索引一样,为了确保良好的性能,还应该注意所创建的 text 索引要能被 RAM 所容纳。创建索引的同时要尽量减少对应用程序的影响

创建文本索引

>db.test.createIndex({“title”:“text”,“body”:text})
与“普通”的多键索引不同,索引中的字段顺序并不重要。默认情况下,text 索引中的每个字段都会被同等对待。可以通过对每个字段指定权重来控制不同字段的相对重要性:
>db.test.createIndex({“title”:text,“body”:“text”},{“weights”:{“title”:3,“body”:2}})
索引一旦创建,就不能改变字段的权重了(除非删除索引再重建),因此在生产环境中创建索引之前应该先在测试数据集上实际操作一下。

对于某些集合,你可能并不知道文档包含哪个字段。可以使用 “$" 在文档的所有字符串字段上创建全文本索引。这样做不仅会对顶层的字符串字段建立索引,也会搜索内嵌文档和数组中的字符串字段。
>db.test.createIndex({"$
”:“text”})

文本查询

可以使用 “$text” 查询运算符对具有 text 索引的集合进行文本搜索。“$text” 会使用空格和大多数标点符号作为分隔符来对搜索字符串进行标记,并在搜索字符串时对所有这些标记执行 OR 逻辑。
>db.test.find({“$text”:{“$search”:“test1 test2”}},{“title”:1}).limit(7);
以上查询查找包含任一“test1”或“test2”词条的所有文章。因为我们的索引是基于文章标题和正文中的词条的,所以这个查询将匹配那些在任何字段中找到这些词条的文档。本例仅对标题字段进行投射,以便在页面上容纳更多的结果。

text 索引有两个问题。第一个问题是,这个查询范围过于广泛,因为 MongoDB使用 OR 逻辑来对“test1”和“test2”进行查询。第二个问题是,在默认情况下,文本搜索不会根据相关性对结果进行排序。

精确匹配,如精确匹配“test1 test2” AND “test3”,此时使用了AND 逻辑
>db.test.find({“$text”:{“$search”:“\“test1 test2\” test3”}},{title:1}).limit(10)
精确匹配“test1 test2” AND (“test3” OR “test4”),此时使用了AND 逻辑
>db.test.find({“$text”:{“$search”:“\“test1 test2\” test3 test4”}},{title:1}).limit(10)
如果想在查询中的各个词条之间使用 AND 逻辑,那么可以将每个词条放在引号中来将其视为一个短语。

使用文本查询会使一些元数据关联到查询结果中。除非使用 $meta 运算符显式地将元数据投射出来,否则元数据不会显示在查询结果中。因此,除了标题之外,我们还将为每个文档计算的相关性分数投射出来。相关性分数存储在名为"textScore" 的元数据字段中。
>db.test.find({“$text”:{“$search”:“\“test1 test2\” test3”}},{title:1,score:{“$meta”:“textScore”}}).sort({score:{“$meta”:“textScore”}})

优化全文本搜索

有几种方式可以优化全文本搜索。如果能够使用某些查询条件将搜索结果的范围变窄,那么可以创建一个由这些查询条件前缀和全文本字段所组成的复合索引:
>db.test.createIndex({“date”:1,“post”:“text”})
这就是分区全文本索引,因为 MongoDB 会基于本例中的 “date” 字段将索引分散为多棵比较小的树。这使得对于特定日期或日期范围进行全文本搜索时会快很多。

在其他语言中搜索

当一个文档被插入(或者索引第一次被创建)后,MongoDB 会查找索引字段并对每个单词进行词干提取,将其减小为一个基本单元。然而,不同语言的词干提取机制是不同的,因此必须指定索引或者文档使用的语言。text 索引允许指定"default_language" 选项,其默认值为 “english”,可以被设置为多种其他语言。
>db.test.createIndex({“key”:“text”},{“default_language”:“french”})
这样一来,除非另外指定,否则这个索引会默认使用法语的词干提取机制。可以在每个文档的基础上使用 “language” 字段来描述文档的语言,从而指定另一种词干提取语言。
>db.test.insert({“username”:“aaa”,language:“swedish”})

固定集合

MongoDB 中的“普通”集合是动态创建的,并且可以自动增长以容纳更多的数据。MongoDB 中还有另一种集合,名为固定集合,此集合需要提前创建好,而且它的大小是固定的,以下图表示新文档被插入队列末尾
在这里插入图片描述
当我们试图向一个已经满了的固定集合中插入数据时,固定集合的行为类似于循环队列:如果空间不足,那么最旧的文档将被删除,新的文档将取而代之,这意味着在插入新文档时,固定集合会自动淘汰最旧的文档。

对于固定集合,有些特定操作是不允许的。例如,无法对文档进行删除(除了前面描述的自动淘汰机制),并且不允许进行会导致文档大小增长的更新。通过阻止这两种操作,可以保证固定集合中的文档以插入顺序进行存储,并且不需要为已删除文档的空间维护空闲列表。

与 MongoDB 中的大部分集合不同,固定集合的访问模式是数据被顺序写入磁盘上的固定空间。这让它们在机械硬盘上的写入速度非常快,尤其是当集合拥有专有的磁盘时(这样便不会被其他集合的随机写操作“打断”)

通常来说,相对于固定集合,MongoDB 优先推荐使用 TTL 索引,因为它们在 WiredTiger 存储引擎中性能更好。TTL 索引会基于日期类型字段的值和索引的 TTL 值而过期,并从普通集合中删除数据。

固定集合不能被分片。如果一个更新或替换操作更改了固定集合中的文档大小,则该操作将失败。

固定集合可以用于记录日志,不过它们不够灵活:除了在创建集合时指定大小,你无法控制数据何时过期。

创建固定集合

不同于普通集合,固定集合在使用前必须被显式创建。可以使用 create 命令创建固定集合。在 shell 中,可以使用 createCollection:
>db.createCollection({“my_collection”,{“capped”:true,“size”:100000}})
上面的命令创建了一个名为 my_collection、大小为 100 000 字节的固定集合。

createCollection 还能够指定固定集合中文档的数量:
>db.createCollection({“my_collection”:{“capped”:true,“size”:100000,“max”:100}})
可以使用这种方式来保存最新的 10 条新闻,或者限制每个用户 1000 个文档。

固定集合一旦创建就无法再改变了。(如果需要修改固定集合的属性,则只能将其删除之后再重建。)因此,在创建大的固定集合之前应该仔细考虑它的大小。

为固定集合指定文档数量的限制时,必须同时指定固定集合的大小。无论先达到哪一个限制,数据替换都会发生:固定集合不能超过 “max” 的数量限制,也不能超过 “size” 的空间限制。

创建固定集合时还有另一个选项,可以将已存在的某个常规集合转换为固定集合。这可以使用 convertToCapped 命令来实现。下面的例子将 test 集合转换为了一个大小为 10 000 字节的固定集合:
>db.runCommand({“convertToCapped”:“test”,“size”:10000})
固定集合是无法转换为普通集合的(除非删除它)

可追加游标

可追加游标(tailable cursor)是一种特殊的游标,当游标的结果集被取光之后,其不会被关闭。可追加游标的灵感来自 tail -f 命令,和这个命令相似,它会尽可能久地持续提取输出结果。由于可追加游标在结果集取光之后不会被关闭,因此当有新文档插入集合中时,游标会继续获取新的结果。由于普通集合并不维护文档的插入顺序,因此可追加游标只能用于固定集合。对于绝大多数的使用场景,建议使用变更流(change stream)来取代可追加游标,因为它提供了更多的控制和配置,并且可以在普通集合中使用。

可追加游标通常用于当文档被插入“工作队列”(固定集合)时对新插入的文档进行处理。如果超过 10 分钟没有新的结果,可追加游标就会被释放,因此当游标被关闭时自动重新执行查询是非常重要的。mongo shell 不允许使用可追加游标

TTL索引

固定集合对于其内容何时被覆盖拥有有限的控制。如果需要更加灵活的过期机制,那么可以使用 TTL 索引,它允许为每一个文档设置一个超时时间。当一个文档达到其预设的过期时间之后就会被删除。这种类型的索引对于类似会话保存这样的缓存场景非常有用。

可以在 createIndex 的第二个参数中指定 “expireAfterSeconds” 选项来创建 TTL索引:
>db.test.createIndex({“lastupdate”:1},{“expireAfterSeconds”:606024}) //超时时间为24小时
这会在 “lastUpdated” 字段上建立一个 TTL 索引。如果一个文档的"lastUpdated" 字段存在并且它的值是日期类型,那么当服务器端时间比文档的"lastUpdated" 字段的时间晚 “expireAfterSeconds” 秒时,文档就会被删除。

为了防止活跃的会话被删除,可以在会话上有活动发生时将 “lastUpdated” 字段的值更新为当前时间。一旦 “lastUpdated” 的时间距离当前时间达到 24 小时,相应的文档就会被删除。

MongoDB 每分钟扫描一次 TTL 索引,因此不应依赖于秒级的粒度。可以使用collMod 命令来修改 “expireAfterSeconds” 的值:
>db.runCommand({“collMod”:“someapp.cache”,“index”:{“keyPattern”:{“lastupdate”:1},“expireAfterSeconds”:3600}})
在一个给定的集合中可以有多个 TTL 索引。TTL 索引不能是复合索引,但是可以像“普通”索引一样用来优化排序和查询。

使用GridFS存储文件

GridFS 是 MongoDB 存储大型二进制文件的一种机制。
一、作为文件存储的理由。
1、使用 GridFS 能够简化技术栈。如果你已经在使用 MongoDB,那么可以使用 GridFS 来代替独立的文件存储工具。
2、GridFS 可以利用 MongoDB 已经设置好的复制或自动分片机制,因此实现故障转移和横向扩展都会更容易一些。
3、当用于存储用户上传的文件时,GridFS 可以解决一些其他文件系统可能会遇到的问题。例如,GridFS 没有在同一个目录下存储大量文件的问题。
二、GridFS 也有一些缺点。
性能比较低。从 MongoDB 中访问文件不如直接从文件系统中访问文件速度快。如果想修改 GridFS 中的文档,则只能先将已有的文档删除,然后再将整个文档重新保存。MongoDB 会将文件作为多个文档进行存储,因此它无法同时对一个文件中的所有块进行加锁。
通常来说,如果你有一些不常改变但是经常需要连续访问的大文件,那么使用GridFS 是非常合适的。
三、GridFS入门:mongofiles
使用 GridFS 最简单的方式是使用 mongofiles 工具。所有的 MongoDB 发行版都包含 mongofiles,它可以用来在 GridFS 中上传文件、下载文件、查看文件列表、搜索文件,以及删除文件。

与其他的命令行工具一样,运行 mongofiles --help 可以查看 mongofiles 的可用选项。

以下会话首先展示了如何使用 mongofiles 从文件系统中上传一个文件到 GridFS,然后列出了 GridFS 中的所有文件,最后将之前上传的文件从 GridFS 中下载了下来:
$ echo “hello world”>foo.txt
$ mongofiles put foo.txt
$ mongofiles list
$ mongofiles get foo.txt
上面的例子使用 mongofiles 执行了 3 种基本操作:put、list 和 get。put 操作可以将文件系统中选定的文件上传到 GridFS。list 操作可以列出 GridFS 中的文件。get 操作可以将 GridFS 中的文件下载到文件系统中,这与 put 操作正好相反。mongofiles 还支持另外两种操作:用于在 GridFS 中搜索文件的 search 操作和用于从 GridFS 中删除文件的 delete 操作。
四、GridFS的底层机制
GridFS 是一个构建于 MongoDB 普通文档之上的轻量级文件存储规范。MongoDB 服务器端几乎不会对 GridFS 请求做任何“特殊”处理,所有工作都由客户端的驱动程序和工具负责。

GridFS 背后的理念是将大文件分割为多个块(chunk),并将每个块作为独立的文档进行存储。由于 MongoDB 支持在文档中存储二进制数据,因此可以将存储的开销降低到最小。除了将文件的每一块单独存储,还有一个文档用于将这些块组织在一起并存储文件的元数据。

GridFS 中的块会被存储到专用的集合中。默认情况下,块使用的集合是fs.chunks,不过这是可以修改的。在块集合内部,各个文档的结构非常简单:
{
“_id”:ObjectId(“…”),
“n”:0,
“data”:BinData(“…”),
“files_id”:ObjectId(“…”)
}
如同其他 MongoDB 文档,块也拥有唯一的 “_id” 字段。另外,还有其他一些键。
“files_id”:包含此块所属文件元数据的文档的 “_id”。
“n”:块在文件中的相对位置。
“data”:块所包含的二进制数据。
每个文件的元数据被保存在一个单独的集合中,默认情况下为 fs.files。这个文件集合中的每个文档表示 GridFS 中的一个文件,文档中可以包含与这个文件相关的任意用户自定义元数据。除了用户自定义的键,还有一些键是 GridFS 规范规定必须要有的。
“_id”:文件的唯一 ID——这个值就是文件的每个块文档中 “files_id” 键的值。
“length”:文件内容的总字节数。
“chunkSize”:组成文件的每个块的大小,单位是字节。这个值默认为 256KB,但可以在需要时进行调整。
“md5”:文件内容的 MD5 校验和,由服务器端生成。

在所有必需的键中,最有趣(或最不言自明)的可能就是 “md5” 了。“md5” 字段的值是由 MongoDB 服务器端使用 filemd5 命令得到的,这个命令可以用来计算所上传块的 MD5 校验和。这意味着用户可以通过检查 “md5” 键的值来确保文件上传的正确性。

正如前面提到的,在 fs.files 中,除了这些必需的字段,同样可以在集合中保存任意的文件元数据。可能你希望在文件的元数据中保存如下载次数、MIME 类型或者用户评分等元数据。

一旦理解了 GridFS 的底层规范,就可以很容易地实现一些驱动程序中没有提供的辅助功能。例如,可以使用 distinct 命令获取存储在 GridFS 中的唯一文件名列表:
>db.fs.files.distinct(“filename”)
这允许应用程序在加载和收集文件信息方面有很大的灵活性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆天至尊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值