我没有使用NoSQL的经验。所以,我认为,如果我只是试着询问代码,我的问题可能是不正确的。相反,让我解释一下我的问题。
假设我有电子商店。我有目录
Catalogs = new Mongo.Collection('catalogs);
和该目录中的产品
Products = new Mongo.Collection('products');
然后,人们将订单添加到临时收集
Order = new Mongo.Collection();
然后,人们提交他们的评论,电话等,并订购。我把它保存到集合操作:
Operations.insert({
phone: "phone",
comment: "comment",
etc: "etc"
savedOrder: Order //<- Array, right? Or Object will be better?
});
很好,但是当我想获得每个产品的统计数据时,运营产品使用的是什么。如何通过我的操作搜索并查找该产品的每项操作?
或者这种方式不好?真正的专业人士如何在现实世界中做到这一点?
答案 0 :(得分:7)
如果我理解得很好,这里有一个存储在Operation
集合中的示例文档:
{
clientRef: "john-001",
phone: "12345678",
other: "etc.",
savedOrder: {
"someMetadataAboutOrder": "...",
"lines" : [
{ qty: 1, itemRef: "XYZ001", unitPriceInCts: 1050, desc: "USB Pen Drive 8G" },
{ qty: 1, itemRef: "ABC002", unitPriceInCts: 19995, desc: "Entry level motherboard" },
]
}
},
{
clientRef: "paul-002",
phone: null,
other: "etc.",
savedOrder: {
"someMetadataAboutOrder": "...",
"lines" : [
{ qty: 3, itemRef: "XYZ001", unitPriceInCts: 950, desc: "USB Pen Drive 8G" },
]
}
},
鉴于此,要查找具有项目引用XYZ001
的所有操作,您只需查询:
> db.operations.find({"savedOrder.lines.itemRef":"XYZ001"})
这将返回整个文档。如果您只对客户端引用(和操作_id)感兴趣,那么您将use a projection as an extra argument to find
:
> db.operations.find({"savedOrder.lines.itemRef":"XYZ001"}, {"clientRef": 1})
{ "_id" : ObjectId("556f07b5d5f2fb3f94b8c179"), "clientRef" : "john-001" }
{ "_id" : ObjectId("556f07b5d5f2fb3f94b8c17a"), "clientRef" : "paul-002" }
如果您需要执行多文档(包括多嵌入文档)操作,您应该查看aggregation framework:
例如,要计算订单总数:
> db.operations.aggregate([
{$match: { "_id" : ObjectId("556f07b5d5f2fb3f94b8c179") }},
{$unwind: "$savedOrder.lines" },
{$group: { _id: "$_id",
total: {$sum: {$multiply: ["$savedOrder.lines.qty",
"$savedOrder.lines.unitPriceInCts"]}}
}}
])
{ "_id" : ObjectId("556f07b5d5f2fb3f94b8c179"), "total" : 21045 }
答案 1 :(得分:1)
我是一个永恒的新手,但由于没有发布回答,我会试一试。
首先,首先安装robomongo或类似的软件,它将允许您直接在mongoDB中查看您的集合(顺便说一下,默认端口是3001)
我处理您的问题的方法是使用_id
字段。它是由mongoDB自动生成的字段,您可以安全地将其用作集合中任何项目的ID。
您的catalog
集合应该有一个名为product
的字符串数组字段,您可以在其中找到所有产品集合项_id
。操作相同:如果订单是产品数组_id
,您可以执行相同操作并将此数组产品_id
存储在savedOrder字段中。如有必要,可以在savedOrder中添加更多字段,例如您使用products
等其他字段创建对象数组discount
。
关于您的查询代码,我假设您一旦弄清楚您的结构是什么就会在网上找到所需的一切。
例如,如果您在saveorder数组中有一个产品数组,则可以将其拉出来:
Operations.find({_id: "your operation ID"},{"savedOrder.products":1)
基本上,您要求在特定操作中使用所有产品_id
。如果您只在一个操作中有多个savedOrders,则可以指定savedOrder _id
,如果您使用的是本地集合中的那个。
Operations.find({_id: "your_operation_ID", "savedOrder._id": "your_savedOrder_ID"},{"savedOrder.products":1)
ps:对于这里的坏人,如果我做错了,请告诉我。
答案 2 :(得分:0)
我找到答案:)当然,这不是真正的专业人士的揭示,但对我来说是一大步。也许我的经验有人觉得有用。使用正确的mongo运算符的所有魔力。让我们用伪代码解决这个问题。
我们有这样的结构:
public void updateNjoftimeList(ArrayList<Njoftime> newList){
for (Njoftime njoftim : newList) {
if (njoftim.getType() == NjoftimeKategori.PUNA_IME.ordinal()) {
rows.add(new PunaImeAdapter(LayoutInflater.from(mContext),
njoftim, mContext));
}
if (njoftim.getType() == NjoftimeKategori.NJOFTIME_CATEGORY.ordinal()) {
rows.add(new OthersAdapter(LayoutInflater.from(mContext),
njoftim, mContext));
}
if (njoftim.getType() == NjoftimeKategori.MAKINA_CATEGORY.ordinal()) {
rows.add(new MakinaAdapter(LayoutInflater.from(mContext),
njoftim, mContext));
}
if (njoftim.getType() == NjoftimeKategori.PRONA_CATEGORY.ordinal()) {
rows.add(new PronaAdapter(LayoutInflater.from(mContext),
njoftim, mContext));
}
}
this.notifyDataSetChanged();
}
如果我们想知道,在什么操作用户使用“banana”,我们应该使用mongoDB运算符“elemMatch”in Mongo docs
Operations:
1. Operation: {
_id: <- Mongo create this unique for us
phone: "phone1",
comment: "comment1",
savedOrder: [
{
_id: <- and again
productId: <- whe should save our product ID from 'products'
name: "Banana",
quantity: 100
},
{
_id:,
productId: <- Another ID, that we should save if order
name: "apple",
quantity: 50
}
]
简单来说,我们得到的文件是我们保存的订单中包含我们想要查找的ID的产品。我不知道这是最好的方式,但它对我有用:)谢谢!