当物流行业遇见MongoDB
簡介
快遞物流系統(tǒng)里最常見的一種業(yè)務(wù)類型就是訂單的查詢和記錄。訂單的特點是隨著遞送過程,訂單數(shù)據(jù)需要隨時更新路徑。數(shù)據(jù)結(jié)構(gòu)上需要可以靈活應(yīng)對,這點非常符合Document模型,并且MongoDB支持GIS功能,非常適用于MongoDB來支撐物流業(yè)務(wù)。并且MongoDB具備Sharding能力,而物流行業(yè)里訂單比較獨立,夸訂單的操作很少,而對單訂單來說,更新追加的操作會較多,比如再物流中轉(zhuǎn)處理上。所以物流業(yè)務(wù)模型上與MongoDB非常的匹配。以下講解一個虛擬的DEMO,可供參考,用到的特性:
- MongoDB Document的數(shù)組結(jié)構(gòu)
- TTL索引,自動過期歷史數(shù)據(jù)
- 復(fù)合索引,多條件查詢索引
- Partial Indexes,條件索引,只索引有效數(shù)據(jù),降低索引的占用空間
- MongoDB GIS功能,支持GeoJSON標(biāo)準(zhǔn),可以接入第三方系統(tǒng)處理GEO信息。
了解阿里云MongoDB詳細(xì)配置及價格
數(shù)據(jù)結(jié)構(gòu)定義
{"_id": <String>, // 訂單ID"status": <String>, // 訂單狀態(tài),shipping,deliveried等"order_image_url": <String>, // 訂單圖片信息"create_date": <ISODate>, // 訂單創(chuàng)建日期"from": { // 發(fā)貨信息"city": <String>, "address": <String>, "name": <String>, "phone": <String>, "location": <GeoJSON> },"delivery": { // 收貨信息"city": <String>, "address": <String>, "name": <String>, "phone": <String>, "location": <GeoJSON> },"details": [ // 物流詳情,數(shù)組結(jié)構(gòu){"action": "reviced", // 物流動作"operator": "快遞小哥1號", // 操作員"date": <ISODate>}...] }例如:
{"_id": "E123456789","status": "delivering","create_date": ISODate("2016-06-21T09:00:00+08:00"),"order_image_url": "http://oss/xxxxx.jpg","from": {"city": "Hangzhou","address": "文一西路969號","name": "小王","phone": "18657112345","location": {"type": "Point","coordinates": [120,30]}},"delivery": {"city": "北京","address": "朝陽區(qū)","name": "朝陽群眾","phone": "18601011011","location": {"type": "Point","coordinates": [116,39]}},"details": [{"action": "reviced","operator": "快遞小哥1號","date": ISODate("2016-06-21T09:00:00+08:00")},{"action": "shipping","station": "hangzhou-airport","date": ISODate("2016-06-22T01:00:00+08:00")},{"action": "shipping","station": "beijing-airport","date": ISODate("2016-06-22T07:00:00+08:00")},{"action": "shipping","station": "chaoyang-station","date": ISODate("2016-06-22T15:00:00+08:00")},{"action": "delivering","operator": "快遞小哥2號","date": ISODate("2016-06-23T10:00:00+08:00")}] }幾個注意點:
- 利用了GEO特性,使用GeoJSON標(biāo)準(zhǔn),但是坐標(biāo)系上需要注意坐標(biāo)標(biāo)準(zhǔn)問題;
- 時間處理上,物流行業(yè)會涉及到國際化,所以嚴(yán)格按照ISO的標(biāo)準(zhǔn),定義時間,CN+80:00;
- 訂單詳情里很好的利用了Document的數(shù)組特性;
- 快遞訂單是唯一的,可以作為MongoDB的主鍵;
insert到collection中后的文檔:
> db.order.find().pretty() {"_id" : "E123456789","status" : "delivering","create_date" : ISODate("2016-06-21T01:00:00Z"),"order_image_url" : "http://oss/xxxxx.jpg","from" : {"city" : "Hangzhou","address" : "文一西路969號","name" : "小王","phone" : "18657112345","location" : {"type" : "Point","coordinates" : [120,30]}},"delivery" : {"city" : "北京","address" : "朝陽區(qū)","name" : "朝陽群眾","phone" : "18601011011","location" : {"type" : "Point","coordinates" : [116,39]}},"details" : [{"action" : "reviced","operator" : "快遞小哥1號","date" : ISODate("2016-06-21T01:00:00Z")},{"action" : "shipping","station" : "hangzhou-airport","date" : ISODate("2016-06-21T17:00:00Z")},{"action" : "shipping","station" : "beijing-airport","date" : ISODate("2016-06-21T23:00:00Z")},{"action" : "shipping","station" : "chaoyang-station","date" : ISODate("2016-06-22T07:00:00Z")},{"action" : "delivering","operator" : "快遞小哥2號","date" : ISODate("2016-06-23T02:00:00Z")}] }數(shù)據(jù)操作
物流快遞的訂單修改主要是查詢和信息追加兩種,主要介紹這兩種:
訂單信息查詢,最常見的操作,用戶的訂單查詢:
db.order.find({_id:"E123456789"});有時需要做信息統(tǒng)計,按照狀態(tài)來查詢:
db.order.find({"status":"delivering", "delivery.city":"北京", "delivery.address":"朝陽區(qū)"});物流狀態(tài)更新時,需要更新相應(yīng)的訂單,MongoDB上直接$push過去即可:
db.order.update( { _id:"E123456789"}, {$push: {details: {"action":"delivering", "operator" : "快遞小哥3號", "date" : ISODate("2016-06-23T13:00:00+8:00")} }})索引創(chuàng)建
_id索引,默認(rèn)存在,不需要再創(chuàng)建;當(dāng)數(shù)據(jù)量較大時,可以使用sharding結(jié)構(gòu),shardkey的選擇上可以使用Hash(_id)。
TTL索引,字段create_date,180天后自動清理數(shù)據(jù):
db.order.createIndex({"create_date":1}, {"expireAfterSeconds":15552000})位置和狀態(tài)索引,為了能快速處理“某地未處理訂單”查詢,這是一個多條件的查詢,所以是一個復(fù)合索引,status字段放在前面,因為多數(shù)的查詢都會依賴狀態(tài)字段
db.order.createIndex({"status":1, "delivery.city":1, "delivery.address":1})在這個Demo里,還有一種加快查詢速度的方法就是,創(chuàng)建一個只包含指定狀態(tài)的一個Partial Indexes索引。比如status必須為delivering?才加入到索引中,有效控制索引的大小,加快查詢速度。
db.order.createIndex({"delivery.city":1, "delivery.address":1},{partialFilterExpression:{'status':{$eq:"delivering"}}})MongoDB GIS
MongoDB遵循的事GeoJSON規(guī)范,對象的描述上通過一個type字段描述GeoJSON類型,coordinates字段描述空間信息。
{ type: "<GeoJSON type>" , coordinates: <coordinates> }
coordinates是一個[longitude, latitude]的數(shù)組類型。另外值得關(guān)注的是MongoDB GEO的使用的是WGS84標(biāo)準(zhǔn)。WGS84也是國際標(biāo)準(zhǔn),中國使用的著名的火星坐標(biāo)GCJ-02,還有一套百度坐標(biāo)BD09,三者的坐標(biāo)轉(zhuǎn)換可以參考附錄相關(guān)的鏈接。
附錄
-
GeoJSON
- https://docs.mongodb.com/manual/reference/geojson/
- http://geojson.org/geojson-spec.html
- https://docs.mongodb.com/manual/reference/glossary/#term-wgs84
-
MongoDB Geo Index
- https://docs.mongodb.com/manual/core/2dsphere/
- https://docs.mongodb.com/manual/reference/glossary/#term-legacy-coordinate-pairs
-
GeoHack
- https://tools.wmflabs.org/geohack/geohack.php?pagename=Hangzhou¶ms=30_15_N_120_10_E_type:city(9018000)_region:CN-33_
- https://tools.wmflabs.org/geohack/geohack.php?pagename=Beijing¶ms=39_55_N_116_23_E_type:city(21700000)_region:CN-11_
- https://en.wikipedia.org/wiki/World_Geodetic_System
-
Geo Datum
https://github.com/wandergis/coordtransform
作者
葉翔,ApsaraDB For MongoDB 開發(fā)組
總結(jié)
以上是生活随笔為你收集整理的当物流行业遇见MongoDB的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++ 的interface
- 下一篇: 大数据七大岗位及职责