国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件

mtunique / 1798人閱讀

摘要:下面列出了使用作為文件存儲的理由。如果已經(jīng)在使用,那么可以使用來代替獨立的文件存儲工具。在中,文件存儲的集中度會比較高,因為是以為單位來分配數(shù)據(jù)文件的。揭開的面紗是一種輕量級的文件存儲規(guī)范,用于存儲中的普通文檔。

上一篇文章:MongoDB指南---14、特殊的索引和集合:固定集合、TTL索引、全文本索引
下一篇文章:MongoDB指南---16、聚合
地理空間索引

MongoDB支持幾種類型的地理空間索引。其中最常用的是2dsphere索引(用于地球表面類型的地圖)和2d索引(用于平面地圖和時間連續(xù)的數(shù)據(jù))。
2dsphere允許使用GeoJSON格式(http://www.geojson.org)指定點、線和多邊形。點可以用形如[longitude, latitude]([經(jīng)度,緯度])的兩個元素的數(shù)組表示:

{
    "name" : "New York City",
    "loc" : {
        "type" : "Point",
        "coordinates" : [50, 2] 
    }
}

線可以用一個由點組成的數(shù)組來表示:

{
    "name" : "Hudson River",
    "loc" : {
        "type" : "Line",
        "coordinates" : [[0,1], [0,2], [1,2]]
    }
}

多邊形的表示方式與線一樣(都是一個由點組成的數(shù)組),但是"type"不同:

{
    "name" : "New England",
    "loc" : {
        "type" : "Polygon",
        "coordinates" : [[0,1], [0,2], [1,2]]
    }
}

"loc"字段的名字可以是任意的,但是其中的子對象是由GeoJSON指定的,不能改變。
在ensureIndex中使用"2dsphere"選項就可以創(chuàng)建一個地理空間索引:

> db.world.ensureIndex({"loc" : "2dsphere"}) 
地理空間查詢的類型

可以使用多種不同類型的地理空間查詢:交集(intersection)、包含(within)以及接近(nearness)。查詢時,需要將希望查找的內(nèi)容指定為形如{"$geometry" : geoJsonDesc}的GeoJSON對象。
例如,可以使用"$geoIntersects"操作符找出與查詢位置相交的文檔:

> var eastVillage = {
... "type" : "Polygon",
... "coordinates" : [
... [-73.9917900, 40.7264100],
... [-73.9917900, 40.7321400],
... [-73.9829300, 40.7321400],
... [-73.9829300, 40.7264100]
... ]}
> db.open.street.map.find(
... {"loc" : {"$geoIntersects" : {"$geometry" : eastVillage}}})

這樣就會找到所有與East Village區(qū)域有交集的文檔。
可以使用"$within"查詢完全包含在某個區(qū)域的文檔,例如:“East Village有哪些餐館?”

> db.open.street.map.find({"loc" : {"$within" : {"$geometry" : eastVillage}}})

與第一個查詢不同,這次不會返回那些只是經(jīng)過East Village(比如街道)或者部分重疊(比如用于表示曼哈頓的多邊形)的文檔。
最后,可以使用"$near"查詢附近的位置:

> db.open.street.map.find({"loc" : {"$near" : {"$geometry" : eastVillage}}})

注意,"$near"是唯一一個會對查詢結(jié)果進行自動排序的地理空間操作符:"$near"的返回結(jié)果是按照距離由近及遠排序的。
地理位置查詢有一點非常有趣:不需要地理空間索引就可以使用"$geoIntersects"或者"$within"("$near"需要使用索引)。但是,建議在用于表示地理位置的字段上建立地理空間索引,這樣可以顯著提高查詢速度。

 復(fù)合地理空間索引

如果有其他類型的索引,可以將地理空間索引與其他字段組合在一起使用,以便對更復(fù)雜的查詢進行優(yōu)化。上面提到過一種可能的查詢:“East Village有哪些餐館?”。如果僅僅使用地理空間索引,我們只能查找到East Village內(nèi)的所有東西,但是如果要將“restaurants”或者是“pizza”多帶帶查詢出來,就需要使用其他索引中的字段了:

> db.open.street.map.ensureIndex({"tags" : 1, "location" : "2dsphere"})

然后就能夠很快地找到East Village內(nèi)的披薩店了:

> db.open.street.map.find({"loc" : {"$within" : {"$geometry" : eastVillage}},
... "tags" : "pizza"})

其他索引字段可以放在"2dsphere"字段前面也可以放在后面,這取決于我們希望首先使用其他索引的字段進行過濾還是首先使用位置進行過濾。應(yīng)該將那個能夠過濾掉盡可能多的結(jié)果的字段放在前面。

 2D索引

對于非球面地圖(游戲地圖、時間連續(xù)的數(shù)據(jù)等),可以使用"2d"索引代替"2dsphere":

> db.hyrule.ensureIndex({"tile" : "2d"})

"2d"索引用于扁平表面,而不是球體表面。"2d"索引不應(yīng)該用在球體表面上,否則極點附近會出現(xiàn)大量的扭曲變形。
文檔中應(yīng)該使用包含兩個元素的數(shù)組表示2d索引字段(寫作本書時,這個字段還不是GeoJSON文檔)。示例如下:

{
    "name" : "Water Temple",
    "tile" : [ 32, 22 ]
}

"2d"索引只能對點進行索引。可以保存一個由點組成的數(shù)組,但是它只會被保存為由點組成的數(shù)組,不會被當成線。特別是對于"$within"查詢來說,這是一項重要的區(qū)別。如果將街道保存為由點組成的數(shù)組,那么如果其中的某個點位于給定的形狀之內(nèi),這個文檔就會與$within相匹配。但是,由這些點組成的線并不一定完全包含在這個形狀之內(nèi)。
默認情況下,地理空間索引是假設(shè)你的值都介于-180~180。可以根據(jù)需要在ensureIndex中設(shè)置更大或者更小的索引邊界值:

> db.star.trek.ensureIndex({"light-years" : "2d"}, {"min" : -1000, "max" : 1000})

這會創(chuàng)建一個2000×2000大小的空間索引。
使用"2d"索引進行查詢比使用"2dsphere"要簡單許多。可以直接使用"$near"或者"$within",而不必帶有"$geometry"子對象。可以直接指定坐標:

> db.hyrule.find({"tile" : {"$near" : [20, 21]}})

這樣會返回hyrule集合內(nèi)的全部文檔,按照距離(20,21)這個點的距離排序。如果沒有指定文檔數(shù)量限制,默認最多返回100個文檔。如果不需要這么多結(jié)果,應(yīng)該根據(jù)需要設(shè)置返回文檔的數(shù)量以節(jié)省服務(wù)器資源。例如,下面的代碼只會返回距離(20,21)最近的10個文檔:

> db.hyrule.find({"tile" : {"$near" : [20, 21]}}).limit(10)

"$within"可以查詢出某個形狀(矩形、圓形或者是多邊形)范圍內(nèi)的所有文檔。如果要使用矩形,可以指定"$box"選項:

> db.hyrule.find({"tile" : {"$within" : {"$box" : [[10, 20], [15, 30]]}}})

"$box"接受一個兩元素的數(shù)組:第一個元素指定左下角的坐標,第二個元素指定右上角的坐標。
類似地,可以使用"$center"選項返回圓形范圍內(nèi)的所有文檔,這個選項也是接受一個兩元素數(shù)組作為參數(shù):第一個元素是一個點,用于指定圓心;第二個參數(shù)用于指定半徑:

> db.hyrule.find({"tile" : {"$within" : {"$center" : [[12, 25], 5]}}})

還可以使用多個點組成的數(shù)組來指定多邊形:

> db.hyrule.find(
... {"tile" : {"$within" : {"$polygon" : [[0, 20], [10, 0], [-10, 0]]}}})

這個例子會查詢出包含給定三角形內(nèi)的點的所有文檔。列表中的最后一個點會被連接到第一個點,以便組成多邊形。

使用GridFS存儲文件

GridFS是MongoDB的一種存儲機制,用來存儲大型二進制文件。下面列出了使用GridFS作為文件存儲的理由。

使用GridFS能夠簡化你的棧。如果已經(jīng)在使用MongoDB,那么可以使用GridFS來代替獨立的文件存儲工具。

GridFS會自動平衡已有的復(fù)制或者為MongoDB設(shè)置的自動分片,所以對文件存儲做故障轉(zhuǎn)移或者橫向擴展會更容易。

當用于存儲用戶上傳的文件時,GridFS可以比較從容地解決其他一些文件系統(tǒng)可能會遇到的問題。例如,在GridFS文件系統(tǒng)中,如果在同一個目錄下存儲大量的文件,沒有任何問題。

在GridFS中,文件存儲的集中度會比較高,因為MongoDB是以2 GB為單位來分配數(shù)據(jù)文件的。

GridFS也有一些缺點。

GridFS的性能比較低:從MongoDB中訪問文件,不如直接從文件系統(tǒng)中訪問文件速度快。

如果要修改GridFS上的文檔,只能先將已有文檔刪除,然后再將整個文檔重新保存。MongoDB將文件作為多個文檔進行存儲,所以它無法在同一時間對文件中的所有塊加鎖。

通常來說,如果你有一些不常改變但是經(jīng)常需要連續(xù)訪問的大文件,那么使用GridFS再合適不過了。

 GridFS入門

使用GridFS最簡單的方式是使用mongofiles工具。所有的MongoDB發(fā)行版中都包含了mongofiles,可以用它在GridFS中上傳文件、下載文件、查看文件列表、搜索文件,以及刪除文件。
與其他的命令行工具一樣,運行mongofiles --help就可以查看它的可用選項了。
在下面這個會話中,首先用mongofiles從文件系統(tǒng)中上傳一個文件到GridFS,然后列出GridFS中的所有文件,最后再將之前上傳過的文件從GridFS中下載下來:

$ echo "Hello, world" > foo.txt
$ ./mongofiles put foo.txt
connected to: 127.0.0.1
added file: { _id: ObjectId("4c0d2a6c3052c25545139b88"),
                filename: "foo.txt", length: 13, chunkSize: 262144,
                uploadDate: new Date(1275931244818),
                md5: "a7966bf58e23583c9a5a4059383ff850" }
done!
$ ./mongofiles list
connected to: 127.0.0.1
foo.txt 13
$ rm foo.txt
$ ./mongofiles get foo.txt
connected to: 127.0.0.1
done write to: foo.txt
$ cat foo.txt
Hello,world

在上面的例子中,使用mongofiles執(zhí)行了三種基本操作:put、list和get。put操作可以將文件系統(tǒng)中選定的文件上傳到GridFS;list操作可以列出GridFS中的文件;get操作與put相反,用于將GridFS中的文件下載到文件系統(tǒng)中。mongofiles還支持另外兩種操作:用于在GridFS中搜索文件的search操作和用于從GridFS中刪除文件的delete操作。

 在MongoDB驅(qū)動程序中使用GridFS

所有客戶端驅(qū)動程序都提供了GridFS API。例如,可以用PyMongo(MongoDB的Python驅(qū)動程序)執(zhí)行與上面直接使用mongofiles一樣的操作:

>>> from pymongo import Connection
>>> import gridfs
>>> db = Connection().test
>>> fs = gridfs.GridFS(db)
>>> file_id = fs.put("Hello, world", filename="foo.txt")
>>> fs.list()
[u"foo.txt"]
>>> fs.get(file_id).read()
"Hello, world"

PyMongo中用于操作GridFS的API與mongofiles非常像:可以很方便地執(zhí)行put、get和list操作。幾乎所有MongoDB驅(qū)動程序都遵循這種基本模式對GridFS進行操作,當然通常也會提供一些更高級的功能。關(guān)于特定驅(qū)動程序?qū)ridFS的操作,可以查詢相關(guān)驅(qū)動程序的文件。

 揭開GridFS的面紗

GridFS是一種輕量級的文件存儲規(guī)范,用于存儲MongoDB中的普通文檔。MongoDB服務(wù)器幾乎不會對GridFS請求做“特殊”處理,所有處理都由客戶端的驅(qū)動程序和工具負責。
GridFS背后的理念是:可以將大文件分割為多個比較大的塊,將每個塊作為獨立的文檔進行存儲。由于MongoDB支持在文檔中存儲二進制數(shù)據(jù),所以可以將塊存儲的開銷降到非常低。除了將文件的每一個塊多帶帶存儲之外,還有一個文檔用于將這些塊組織在一起并存儲該文件的元信息。
GridFS中的塊會被存儲到專用的集合中。塊默認使用的集合是fs.chunks,不過可以修改為其他集合。在塊集合內(nèi)部,各個文檔的結(jié)構(gòu)非常簡單:

{
    "_id" : ObjectId("..."),
    "n" : 0,
    "data" : BinData("..."),
    "files_id" : ObjectId("...")
}

與其他的MongoDB文檔一樣,塊也都擁有一個唯一的"_id"。另外,還有如下幾個鍵。

"files_id"

塊所屬文件的元信息。

"n"

塊在文件中的相對位置。

"data"

塊所包含的二進制數(shù)據(jù)。

每個文件的元信息被保存在一個多帶帶的集合中,默認情況下這個集合是fs.files。這個文件集合中的每一個文檔表示GridFS中的一個文件,文檔中可以包含與這個文件相關(guān)的任意用戶自定義元信息。除用戶自定義的鍵之外,還有幾個鍵是GridFS規(guī)范規(guī)定必須要有的。

"_id"

文件的唯一id,這個值就是文件的每個塊文檔中"files_id"的值。

"length"

文件所包含的字節(jié)數(shù)。

"chunkSize"

組成文件的每個塊的大小,單位是字節(jié)。這個值默認是256 KB,可以在需要時進行調(diào)整。

"uploadDate"

文件被上傳到GridFS的日期。

"md5"

文件內(nèi)容的md5校驗值,這個值由服務(wù)器端計算得到。

這些必須字段中最有意思(或者說能夠見名知意)的一個可能是"md5"。"md5"字段的值是由MongoDB服務(wù)器使用filemd5命令得到的,這個命令可以用來計算上傳到GridFS的塊的md5校驗值。這意味著,用戶可以通過檢查文件的md5校驗值來確保文件上傳正確。
如上面所說,在fs.files中,除了這些必須字段外,可以使用任何自定義的字段來保存必需的文件元信息。可能你希望在文件元信息中保存文件的下載次數(shù)、MIME類型或者用戶評分。
只要理解了GridFS底層的規(guī)范,自己就可以很容易地實現(xiàn)一些驅(qū)動程序沒有提供的輔助功能。例如,可以使用distinct命令得到GridFS中保存文件的文件名集合(集合中的每個文件名都是唯一的)。

> db.fs.files.distinct("filename")
[ "foo.txt" , "bar.txt" , "baz.txt" ]

這樣,在加載或者收集文件相關(guān)信息時,應(yīng)用程序可以擁有非常大的靈活性.

上一篇文章:MongoDB指南---14、特殊的索引和集合:固定集合、TTL索引、全文本索引
下一篇文章:MongoDB指南---16、聚合

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/19576.html

相關(guān)文章

  • MongoDB指南---15特殊索引集合地理空間索引使用GridFS存儲文件

    摘要:下面列出了使用作為文件存儲的理由。如果已經(jīng)在使用,那么可以使用來代替獨立的文件存儲工具。在中,文件存儲的集中度會比較高,因為是以為單位來分配數(shù)據(jù)文件的。揭開的面紗是一種輕量級的文件存儲規(guī)范,用于存儲中的普通文檔。 上一篇文章:MongoDB指南---14、特殊的索引和集合:固定集合、TTL索引、全文本索引下一篇文章:MongoDB指南---16、聚合 地理空間索引 MongoDB支持...

    2i18ns 評論0 收藏0
  • MongoDB指南---14、特殊索引集合:固定集合、TTL索引、全文本索引

    摘要:固定集合不能被分片。為固定集合指定文檔數(shù)量限制時,必須同時指定固定集合的大小。沒有索引的集合默認情況下,每個集合都有一個索引。 上一篇文章:MongoDB指南---13、索引類型、索引管理下一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件 本章介紹MongoDB中一些特殊的集合和索引類型,包括: 用于類隊列數(shù)據(jù)的固定集合(capped...

    cikenerd 評論0 收藏0
  • MongoDB指南---14、特殊索引集合:固定集合、TTL索引、全文本索引

    摘要:固定集合不能被分片。為固定集合指定文檔數(shù)量限制時,必須同時指定固定集合的大小。沒有索引的集合默認情況下,每個集合都有一個索引。 上一篇文章:MongoDB指南---13、索引類型、索引管理下一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件 本章介紹MongoDB中一些特殊的集合和索引類型,包括: 用于類隊列數(shù)據(jù)的固定集合(capped...

    QLQ 評論0 收藏0
  • MongoDB指南---16、聚合

    摘要:將返回結(jié)果限制為前個。所以,聚合的結(jié)果必須要限制在以內(nèi)支持的最大響應(yīng)消息大小。包含字段和排除字段的規(guī)則與常規(guī)查詢中的語法一致。改變字符大小寫的操作,只保證對羅馬字符有效。只對羅馬字符組成的字符串有效。 上一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件下一篇文章:MongoDB指南---17、MapReduce 如果你有數(shù)據(jù)存儲在Mon...

    Keagan 評論0 收藏0
  • MongoDB指南---16、聚合

    摘要:將返回結(jié)果限制為前個。所以,聚合的結(jié)果必須要限制在以內(nèi)支持的最大響應(yīng)消息大小。包含字段和排除字段的規(guī)則與常規(guī)查詢中的語法一致。改變字符大小寫的操作,只保證對羅馬字符有效。只對羅馬字符組成的字符串有效。 上一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件下一篇文章:MongoDB指南---17、MapReduce 如果你有數(shù)據(jù)存儲在Mon...

    _Zhao 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<