位置、时间序列、向量、附件与媒体
geopoint 与 geoshape、时间序列属性、向量、附件、媒体引用、加密文本:各存什么,各有什么限制。

本课目标
读完这一课,你将能够
- 说出位置、时间序列、向量、附件、媒体引用和加密文本各存什么
- 写出它们的取值形状,说出各自的限制
- 判断一个需求该用时间序列属性、向量,还是别的建模方式
位置:geopoint 和 geoshape
上一节的类型表里,有几种存的不是「一个数字或一段文字」。这一节把它们逐个讲清:位置、时间序列、向量,以及附件和媒体。
示例工厂的客户有城市,也有地图上的一个点。这个点就是 geopoint 属性 customer.location,存一个 GeoJSON 点,坐标是常见的经纬度(WGS 84)。
GeoJSON 的坐标是先经度、后纬度,这是最容易写反的地方。苏州大约在东经 120.6、北纬 31.3,所以写成 [120.5853, 31.2989];写反了,点会落到海里。
{ "customerId": "C-1008", "location": { "type": "Point", "coordinates": [120.5853, 31.2989] } }
对象有了 geopoint,搜索里就能用 withinDistanceOf(离某个点多远以内)和 withinBoundingBox(在某个方框里),「离这家工厂 50 公里内的客户」变成一步查询。
geoshape 存线和面,比如厂区边界、配送路线。写它要守 GeoJSON 的规则:只能是 LineString、Polygon、MultiLineString、MultiPolygon 或 MultiPoint,不能是 Feature、FeatureCollection 或 GeometryCollection;多边形要闭合,外环逆时针,不能自己交叉。单个点别用 geoshape,用 geopoint。geopoint 能做标题键,geoshape 不能。
时间序列:随时间变化的读数
设备每分钟报一次振动和温度,一天就是 1,440 个读数。这些读数不该变成一个个对象,也不该塞进数组,它们属于 timeseries 属性。
每分钟一个读数,建成 reading 对象:一台设备一年就是 50 多万个对象,全是同一种东西。
machine.vibration 和 machine.temperature 是两个 timeseries 属性。越线这件事(一次报警)才值得建成对象。
时间序列属性存的不是一个值,而是一条序列,值写成 { seriesId },读取时按需取点:firstPoint、lastPoint 或 streamPoints。它不能做主键或标题键,也不能放进数组。对象的值里还可以直接带上最多 1,000 个点:
{
"machineId": "M-0007",
"vibration": {
"seriesId": "M-0007-vibration",
"points": [
{ "time": "2026-09-28T08:00:00Z", "value": 2.4 },
{ "time": "2026-09-28T08:01:00Z", "value": 2.6 }
]
}
}
每台设备都有振动和温度读数,所以它们直接放在 machine 上,「这台设备最新的振动」就成了一个属性的一次读取。读最新一点用 lastPoint。新本体集成使用已有对应端点的 /api/v2 接口。时间序列尚无可用的 v2 后继,不能只把旧地址的 v1 换成 v2。如果读数只有一部分设备才有,比如只有几台带流量计,就别在 machine 上加一堆大多为空的时间序列属性,而是另建一个传感器对象类型,再用关系连到设备。
向量:给相似性搜索用
向量(vector)是一串数字,通常是一段文字的嵌入:意思相近的文字,向量也靠得近。给缺陷的描述配一个向量,就能问「找出和这条最像的缺陷」,不用靠关键词碰运气。
缺陷的 description 由质检员随手写,措辞各不相同,正适合用向量找相似。给 defect 加一个向量属性:
{ "name": "descriptionVector", "type": "vector", "vectorDimension": 768, "title": "Description embedding" }
- 定义里要写
vectorDimension(维数),由生成向量的模型决定,例如 768。只有同一个模型生成的向量才能互相比较;维数不要超过 2048,这是通行的上限。 - 向量不能做主键或标题键,也不能放进数组。
- 向量不能筛选、不能比大小,只能做最近邻搜索。
- 向量又长又不好读,不明确选取它,读对象时不会带上。
附件、媒体引用与加密文本
附件
存一个文件,例如供应商的资质证书。值是 { rid },不能做主键或标题键。
媒体引用
指向一张图片、一段视频或音频,例如质检照片 inspection.photo。值是 { mimeType, reference }。
加密文本
存一段经加密服务编码的字符串,例如联系电话。可以做标题键,不能做主键。
三者的共同点是:属性里只有一个指针或一段密文,真正的文件和明文在别处。
下一节讲怎样在一个属性里放几个字段,以及让多个对象类型共用同一个属性定义。
要点
geopoint存一个点,GeoJSON 先经度后纬度;geoshape存线和面,单个点别用它。- 时间序列属性存一条读数序列,用
firstPoint、lastPoint、streamPoints读;不能做键,也不能放进数组。 - 每个对象都有的读数放在对象上;只有部分对象才有的,另建传感器对象。
- 向量只能做最近邻搜索,要给维数,不能做键,也不能放进数组。
- 附件、媒体引用、加密文本的值形状能存能读。附件上传和 Media sets 已提供;解密与地理时序服务仍未实现。
练一练
给设备和缺陷补上特殊类型
示例工厂的设备有振动和温度读数,缺陷有一段文字描述。
为 machine 写 vibration 和 temperature 两个 timeseries 属性的定义,再造一条带两个点的取值。
用 GeoJSON 写出苏州(东经 120.5853,北纬 31.2989)的 geopoint;再故意写反经纬度,想想点会落在哪里。
三个需求各该用什么类型:设备每秒一个温度读数;找出和一条缺陷描述最像的历史缺陷;给每次质检存一张照片。
小测
选一个答案,马上看解析。
Q1苏州(东经 120.5853,北纬 31.2989)的 geopoint 怎么写?
GeoJSON 规定先经度、后纬度。平台不会替你猜顺序,写反了点就落在错的地方。
Q2设备每分钟一个温度读数,一台设备一年 50 多万个点。怎么建模?
时间序列属性专为这种读数设计,按需读首点、末点或一段。每个读数一个对象会让对象数暴涨;数组适合放少量同类值,不适合放不断增长的读数。
Q3下面哪个类型可以做标题键?
geopoint 和 cipherText 可以做标题键,但都不能做主键。vector、timeseries、geoshape 等两个都不能做。