MongoDB助力快速搭建物流订单系统

简介

快递物流系统里最常见的一种业务类型就是订单的查询和记录。订单的特点是随着递送过程,订单数据需要随时更新路径。数据结构上需要可以灵活应对,这点非常符合Document模型,并且MongoDB支持GIS功能,非常适用于MongoDB来支撑物流业务。并且MongoDB具备Sharding能力,而物流行业里订单比较独立,夸订单的操作很少,而对单订单来说,更新追加的操作会较多,比如再物流中转处理上。所以物流业务模型上与MongoDB非常的匹配。以下讲解一个虚拟的DEMO,可供参考,用到的特性:

  • MongoDB Document的数组结构
  • TTL索引,自动过期历史数据
  • 复合索引,多条件查询索引
  • Partial Indexes,条件索引,只索引有效数据,降低索引的占用空间
  • MongoDB GIS功能,支持GeoJSON标准,可以接入第三方系统处理GEO信息。

数据结构定义

{
  "_id": <String>,  // 订单ID
  "status": <String>, // 订单状态,shipping,deliveried等
  "order_image_url": <String>, // 订单图片信息
  "create_date": <ISODate>, // 订单创建日期
  "from": {    // 发货信息
      "city": <String>,  "address": <String>,
      "name": <String>,  "phone": <String>,
      "location": <GeoJSON>
  },
  "delivery": {    // 收货信息
      "city": <String>,  "address": <String>,
      "name": <String>,  "phone": <String>,
      "location": <GeoJSON>
  },
  "details": [   // 物流详情,数组结构
    {
      "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": "朝阳区",
    "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标准,但是坐标系上需要注意坐标标准问题;
  • 时间处理上,物流行业会涉及到国际化,所以严格按照ISO的标准,定义时间,CN+80:00 ;
  • 订单详情里很好的利用了Document的数组特性;
  • 快递订单是唯一的,可以作为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" : "朝阳区",
        "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")
        }
    ]
}

数据操作

物流快递的订单修改主要是查询和信息追加两种,主要介绍这两种:

订单信息查询,最常见的操作,用户的订单查询:

db.order.find({_id:"E123456789"});

有时需要做信息统计,按照状态来查询:

db.order.find({"status":"delivering", "delivery.city":"北京", "delivery.address":"朝阳区"});

物流状态更新时,需要更新相应的订单,MongoDB上直接 $push 过去即可:

db.order.update( { _id:"E123456789"},
{$push: {details:
{"action":"delivering", "operator" : "快递小哥3号", "date" : ISODate("2016-06-23T13:00:00+8:00")}
}})

索引创建

_id 索引,默认存在,不需要再创建;当数据量较大时,可以使用sharding结构,shardkey的选择上可以使用 Hash(_id) 。

TTL索引,字段 create_date ,180天后自动清理数据:

db.order.createIndex({"create_date":1}, {"expireAfterSeconds":15552000})

位置和状态索引,为了能快速处理“某地未处理订单”查询,这是一个多条件的查询,所以是一个复合索引, status 字段放在前面,因为多数的查询都会依赖状态字段

db.order.createIndex({"status":1, "delivery.city":1, "delivery.address":1})

在这个Demo里,还有一种加快查询速度的方法就是,创建一个只包含指定状态的一个Partial Indexes索引。比如 status 必须为 delivering  才加入到索引中,有效控制索引的大小,加快查询速度。

db.order.createIndex({"delivery.city":1, "delivery.address":1},{partialFilterExpression:{‘status‘:{$eq:"delivering"}}})

MongoDB GIS

MongoDB遵循的事GeoJSON规范,对象的描述上通过一个type字段描述GeoJSON类型,coordinates字段描述空间信息。

{ type: "<GeoJSON type>" , coordinates: <coordinates> }

coordinates是一个 [longitude, latitude] 的数组类型。另外值得关注的是MongoDB GEO的使用的是WGS84标准。WGS84也是国际标准,中国使用的著名的火星坐标GCJ-02,还有一套百度坐标BD09,三者的坐标转换可以参考附录相关的链接。

附录

时间: 2025-01-08 00:52:07

MongoDB助力快速搭建物流订单系统的相关文章

使用ASP.NET MVC+Entity Framework快速搭建博客系统

学习 ASP.NET MVC 也有一段时间了,打算弄个小程序练练手,做为学习过程中的记录和分享. 首先,得确定需求,木有需求的话,那还搞个毛线呀!嗯--大致思考了一下,终于得出如下需求: 1.能自定义分类 2.能发文章 OK!就这样,先从简单的开始(其实是复杂的不会做),后面有需要再添加(希望水平能达到).功能确定了,那么改确定要做成什么样子的了.先和度娘商量一下先-- 终于在我的淫威之下,度娘交出了一个比较简洁的,源网站在这里(表示感谢),被小弟阉割了之后效果如下图: 接下来就开始编码了么?嗯

快速搭建phpwind论坛系统

摘要: phpwind 是采用 PHP + MySQL 方式运行的开源社区程序.轻架构,高效率简易开发,帮助您快速搭建并轻松管理社区站点.本文介绍如何使用云市场的 PHPWind论坛系统(含智慧云虚机面板) 快速搭建论坛. phpwind 是采用 PHP + MySQL 方式运行的开源社区程序.轻架构,高效率简易开发,帮助您快速搭建并轻松管理社区站点.phpwind 提供了 2 款完全不同的版本,分别是拥有成熟功能.海量插件支撑的 phpwind 稳定版(v8.7.1)和注重轻社区.高效.易开发

企业如何快速搭建大数据处理系统

随着互联网+时代的来临,互联网已经从InformationTechnology (IT)时代过度到Data Technology (DT)时代,数据量也以几何量级递增,数据整体呈现出5V特征,大体量(Volume).多样性(Variety).时效性(Velocity).准确性(Veracity),大价值(Value).大体量体现为数据量可以从TB到PB,甚至到EB规模,google资料显示,其每天搜索提供的数量达到30PB(1P=1024TB), 这些数据如果打印出来将超过5千万亿张A4纸,但是

如何快速搭建系统原型

如何快速搭建系统原型 2018年4月16日luodonggan 本文是我对现阶段学习和接触到的系统项目总结,将系统界面各部分模块化/组件化,编写了系统通用交互方案,旨在帮助交互设计师.项目经理通过通用方案可以根据项目需求快速搭建合适的系统界面. 背景 最近负责了多个系统的交互设计工作,在设计的过程中遇到了一些问题:界面布局应该怎么设计,这个功能怎么放,首页要放什么内容.这边放这些功能合适吗.弹窗展示是否合适……设计好了又发现需要个性化,开发成本较高,标准版不支持. 所以,我想有没有一套方案,可以

如何快速搭建一个完整的移动直播系统?

移动直播行业的火热会在很长一段时间内持续,通过和各行业的整合,从而成为具有无限可能性的行业.主要因为以下三个原因: 第一,移动直播的UGC生产模式比PC端的直播更明显,人人都有设备,随时随地开播,完全顺应了互联网时代的开放性原则,能刺激更多人去创造和传播优质内容. 第二,网络带宽和速度在逐渐提高,网络成本在逐渐下降,为移动直播提供一个极佳的发展环境.文字.声音.视频.游戏等都会在移动直播中呈现,创造出更加丰富的用户体验.直播可以以SDK的形式接入到自己的应用中,比如,教育领域中的课后辅导完全可以

一文教您如何通过 Docker 快速搭建各种测试环境(Mysql, Redis, Elasticsearch, MongoDB) | 建议收藏

原文:一文教您如何通过 Docker 快速搭建各种测试环境(Mysql, Redis, Elasticsearch, MongoDB) | 建议收藏 欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 高级架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.exception.site 小哈今天给大家分享的主题是,如何通过 Docker 快速搭建各种测试环境,本文列举的,也是小哈在工作中经常用到的,其中包括 Mysql

DigitalOcean上使用Tornado+MongoDB+Nginx+Supervisor+DnsPod快速搭建个人博客

DigitalOcean 之前买了个便宜的VPS并且在上面搭建了我自己写的博客程序,后来VPS里运行MongoDB经常自己挂掉就索性没理了.直到现在VPS已经过期,服务器被强制关掉了.周末在家索性想着把这个博客程序重新搭建起来. 选择Linode还是云主机(阿里云等等)?阿里云貌似有些贵,而且还有一堆备案的流程.Linode最近推出SSD服务,20刀/月的价格,加量不加价,很是吸引人.但无奈还是花的有些心疼.忽然另外一个VPS服务DigitalOcean(链接含refcode喔)被我无意发现.D

乐视秒杀架构解读:从零开始搭建百万每秒订单系统

在各种秒杀活动大行其道的今天,订单系统的性能与稳定日益重要.乐视集团作为这一技术的佼佼者,在多次的电商狂欢节中都能抢占商机.拔得头筹,其表现无疑为其他企业和厂商提供了非常有价值的参考. 在Gdevops全球敏捷运维峰会北京站的现场,乐视BOSS平台技术部架构师梁阳鹤就给大家带来了<从零开始搭建百万每秒订单系统>的精彩演讲.从部分到整体,从微观到宏观,层层递进,步步为营,详尽地介绍了整套乐视支付架构及其实现每秒处理百万笔交易的成功要点. (点击“这里”听梁阳鹤演讲完整录音) 演讲主要分为三个部分

mongodb集群快速搭建

记录这个纯属方便自己以后使用.. mongodb官方最新版本3.2.6,某些功能都加以改进并且性能提升很大,下面操作只是快速搭建mongodb复制集以及shard分片等 一共分为如下几步骤 启动某个节点主master进行设置单个节点账号和密码 配置mongodb复制集 配置mongos-shard分片 设置mongos路由账号和密码并启用验证 架构图如下  目录规划创建 mkdir /data/{config,shard1,shard2,shard3,mongos,logs,configsvr,