当前位置: 首页 > news >正文

Voyage系列3: 技巧与提示

本章汇集了多年来大家积累的一些实用技巧与心得,由萨宾娜·马纳撰写。

如何通过id查询对象

若已知_id值,可将其初始化为OID并进行查询。

Person selectOne: {('_id' -> (OID value: 16r55CDD2B6E9A87A520F000001))} asDictionary.

请注意以下两种方式是等效的:

OID value: 26555050698940995562836590593. "dec"
OID value: 16r55CDD2B6E9A87A520F000001. "hex"

或者,如果您拥有一个根集合中的实例(本例中为Person实例),可以直接获取其voyageId并用于查询。以下示例假设存在Trips和Persons两个根集合:行程数据中包含嵌入的收据集合,而收据具有description属性。该查询将检索指定人员所有至少包含一张描述为aString的收据的行程记录。

 TripselectMany:{('receipts.description' -> aString).('person._id' -> aPerson voyageId)} asDictionary

尚未支持的Mongo命令

indexes

目前尚无法通过Voyage直接创建和删除索引,但您可以使用OSProcess来实现。

假设您有一个名为myDB的数据库,其中包含名为Trips的集合。行程数据中嵌有收据集合,而收据具有名为description的属性。此时您可以通过以下方式在description字段上创建索引:

OSProcess command:
'/{pathToMongoDB}/MongoDB/bin/mongo --eval "db.getSiblingDB(''myDB'').Trips.createIndex({''receipts.description'':1})"'

通过以下命令删除Trips集合中的所有索引:

OSProcess command:
'/{pathToMongoDB}/MongoDB/bin/mongo --eval "db.getSiblingDB(''myDB'').Trips.dropIndexes()"'

Backup

目前尚无法通过Voyage直接创建备份,请使用

OSProcess command:'/{pathToMongoDB}/MongoDB/bin/mongodump  --out {BackupPath}'

请参阅MongoDB文档了解相关命令,特别是--eval命令的使用方法。

有用的mongo命令

在mongo控制台中使用“.explain()”来确认查询是否真正使用了索引。

例如:

在嵌入式属性(description)上创建索引:

> db.Trips.createIndex({"receipts.description":1})

执行查询并调用explain方法。可见仅扫描了2个文档:

db.Trips.find({"receipts.description":"a"}).explain("executionStats")
{
"cursor" : "BtreeCursor receipts.receiptDescription_1",
"isMultiKey" : true,
"n" : 2,
"nscannedObjects" : 2,
"nscanned" : 2,
"nscannedObjectsAllPlans" : 2,
"nscannedAllPlans" : 2,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"receipts.receiptDescription" : [
["a", "a"]
]
},
"allPlans" : [
{
"cursor" : "BtreeCursor receipts.receiptDescription_1",
"n" : 2,
"nscannedObjects" : 2,
"nscanned" : 2,
"indexBounds" : {
"receipts.receiptDescription" : [
["a", "a"]
]
}
}
],
"server" : "MacBook-Pro-Sabine.local:27017"
}

现在,删除索引

> db.Trips.dropIndexes()
{"nIndexesWas" : 2,"msg" : "non-_id indexes dropped for collection","ok" : 1
}

再次执行查询,此时会扫描所有文档。

> db.Trips.find({"receipts.receiptDescription":"a"}).explain("executionStats")
{"cursor" : "BasicCursor","isMultiKey" : false,"n" : 2,"nscannedObjects" : 246,"nscanned" : 246,"nscannedObjectsAllPlans" : 246,"nscannedAllPlans" : 246,"scanAndOrder" : false,"indexOnly" : false,"nYields" : 0,"nChunkSkips" : 0,"millis" : 1,"indexBounds" : {},"allPlans" : [{"cursor" : "BasicCursor","n" : 2,"nscannedObjects" : 246,"nscanned" : 246,"indexBounds" : {}}],"server" : "MacBook-Pro-Sabine.local:27017"
}

在MongoDB中存储Date类型的实例

MongoDB存在一个已知问题:无法区分Date和DateAndTime类型。因此即使您存储的是Date类型,查询返回的将是DateAndTime类型。在具体化对象时,您需要手动将其转换回Date类型。

数据库设计

对象结构通常不会形成简单的树形关系,而是包含循环引用的图结构。例如,人员对象可能指向其行程记录,而每个行程记录又关联到对应的人员(形成Person<->>Trip双向关系)。通过分别为Persons和Trips创建根集合,可以避免生成无限循环(详见第1.2章说明)。

这是一个行程指向另一个根集合中人员对象的示例,同时还涉及另一个根集合paymentMethod。需要注意的是,收据也反向指向行程,但这并不会形成循环引用。

Trip
{"_id" : ObjectId("55cf2bc73c9b0fe702000008"),
"#version" : 876079653,
"person" : {"#collection" : "Persons","_id" : ObjectId("55cf2bbb3c9b0fe702000007") },
"receipts" : [{ "currency" : "EUR","date" : { "#instanceOf" : "ZTimestamp", "jdn" : 2457249, "secs" : 0 },"exchangeRate" : 1,"paymentMethod" : {"#collection" : "PaymentMethods","_id" : ObjectId("55cf2bbb3c9b0fe702000003") },"receiptDescription" : "Taxi zum Hotel","receiptNumber" : 1,"trip" : {"#collection" : "Trips","_id" : ObjectId("55cf2bc73c9b0fe702000008") } } ],"startPlace" : "Österreich","tripName" : "asdf","tripNumber" : 1 }

对应的人员对象会指向其所有行程记录以及所属公司

{ "#version" : 714221829,
"_id" : ObjectId("55cf2bbb3c9b0fe702000007"),
"bankName" : "","company" : {
"#collection" : "Companies",
"_id" : ObjectId("55cf2bbb3c9b0fe702000002") },
"email" : "bb@spesenfuchs.de",
"firstName" : "Berta",
"lastName" : "Block",
"roles" : [  "user" ],
"tableOfAccounts" : "SKR03",
"translator" : "German",
"trips" : [
{
"#collection" : "Trips",
"_id" : ObjectId("55cf2bc73c9b0fe702000008") } ] }

如果您的业务领域存在严格划分的区域(例如客户管理),可以考虑为每个区域(客户)创建独立的存储库。

数据检索

问题是:能否从Mongo集合中检索即使该数据库并非通过Voyage创建的数据?答案是肯定的。以下是解决方案。

首先我们创建一个包含两个类方法的MyClass:

MyClass class >> isVoyageRoot^ true
MyClass class >> descriptionContainer<voyageContainer>^ VOContainer newcollectionName: 'myCollection';yourself

此外,为了正确读取数据,需要根据数据库中的内容添加相应的实例变量。

例如,若数据库中存在以下存储信息:

{ "_id" : ObjectId("5900a0175bc65a2b7973b48a"), "item" : "canvas", "qty" : 100, "tags" : [ "cotton" ] }

此时MyClass应包含实例变量:item、qty、tags及相应的访问方法。随后我们在类端定义以下描述:

MyClass class >> mongoItem<mongoDescription>^ VOToOneDescription newattributeName: 'item';kind: String;yourself
MyClass class >> mongoQty<mongoDescription>^ VOToOneDescription newattributeName: 'qty';kind: Integer;yourself
MyClass class >> mongoTags<mongoDescription>^ VOToOneDescription newattributeName: 'tags';kind: OrderedCollection;yourself

此后便可连接数据库并获取信息。

| repository |
repository := VOMongoRepository database: 'databaseName'.
repository selectAll: MyClass
http://www.hskmm.com/?act=detail&tid=39835

相关文章:

  • 合规与创新并重:现代企业DevOps平台的安全战略与实践路径
  • 完全开源!一款基于 SpringBoot + Vue 构建的社区平台!
  • 【一步步开发AI运动APP】十二、如何进行运动开始前的站位预检,提升用户体验
  • Oracle Data Pump 网络模式直接迁移详解(使用数据库链接(Database Link))
  • 2025年10月洗地机产品推荐:五款高口碑机型横向对比榜
  • 2025年10月防脱生发产品推荐:十款口碑榜对比与临床数据全解析
  • 2025年10月美容仪品牌推荐:无创无痛纳晶领衔性价比排行榜
  • 2025 年娱乐麦克风,一拖二无线麦克风,舞台演出麦克风厂家最新推荐,技术实力与市场口碑深度解析
  • 2025年10月工装装修公司推荐榜:全国服务实力对比
  • 使用Voyage持久化对象
  • 2025年10月品牌认证机构推荐:权威榜单对比五强优劣
  • 2025 年安全防坠器厂家最新推荐排行榜权威发布,结合中国安全防护用品行业协会测评数据揭晓行业实力企业成都安全防坠器/安全防坠器测试厂家推荐
  • 矢量图
  • 泛型通配符 T、E、K、V、?
  • 2025 年最新推荐 PPT 生成软件排行榜:权威协会测评 + AI 备案技术加持,3500 万用户信赖之选全面解析
  • 2025 年减速器源头厂家最新推荐榜:RV / 精密 / 通用减速器测试品牌技术实力权威测评
  • 20232413 2025-2026-1 《网络与系统攻防技术》实验三实验报告
  • 上周热点回顾(10.20
  • 2025 年电驱动厂家最新推荐排行榜:依托国家智能测控系统产业计量测试联盟测评数据,精选伺服电机、新能源汽车电机等领域优质品牌
  • 2025 亲测!永久删除的照片这样救,完整指南来了
  • 2025 年阳台光伏厂家最新推荐榜:技术实力与市场口碑深度解析,含逆变器/储能/光伏板优质企业
  • 折旧分配表点击修改按钮报错,软件卡死
  • 命令行数据科学实用指南-全-
  • 10 25
  • 线性表
  • 2025 年不锈钢护栏厂家最新推荐排行榜:含河道、桥梁防撞、201/316L 材质、景观灯光类产品,精选高性能优质品牌
  • 日记17
  • 日记16
  • 架构师必备:限流方案选型(使用篇)
  • 10月第一篇