我正在学习如何使用MongoDB。我花了一些时间将我的心态从RDBMS / SQL改为NoSQL。
使用下面的表和查询作为示例,我希望有人可以解释如何使用mongrel实现这个简单的RDBMS架构,以及如何使用mongodb实现查询。
CREATE TABLE tag_category (id INT NOT NULL, name VARCHAR(32) );
CREATE UNIQUE INDEX idxu_tag_cat ON tag_category(name);
INSERT INTO tag_category(1, 'books');
INSERT INTO tag_category(3, 'music');
INSERT INTO tag_category(4, 'food');
CREATE TABLE tag (id INT NOT NULL,
categ_id INT REFERENCES tag_category(id),
tagval VARCHAR(32) NOT NULL
);
INSERT INTO tag (1,1,'romance');
INSERT INTO tag (2,1,'scifi');
INSERT INTO tag (3,1,'thriller');
INSERT INTO tag (4,2,'rap');
INSERT INTO tag (5,2,'country');
INSERT INTO tag (6,2,'jazz');
INSERT INTO tag (7,2,'classical');
INSERT INTO tag (8,3,'Chinese');
INSERT INTO tag (9,3,'Italian');
INSERT INTO tag (10,3,'French');
INSERT INTO tag (11,3,'South African');
CREATE TABLE item (id INT,
entry_date DATE NOT NULL,
name VARCHAR(32) );
CREATE UNIQUE INDEX idxu_item ON item(name);
INSERT INTO item (id, entry_date, name) VALUES(1, '2011-01-01', 'A love supreme');
INSERT INTO item (id, entry_date, name) VALUES(2, '2011-01-01', 'A kind of blue');
INSERT INTO item (id, entry_date, name) VALUES(3, '2011-02-01', 'Believe the hype');
INSERT INTO item (id, entry_date, name) VALUES(4, '2011-01-01', 'Raising Hell');
INSERT INTO item (id, entry_date, name) VALUES(5, '2011-01-01', 'The Chronic');
INSERT INTO item (id, entry_date, name) VALUES(6, '2011-02-01', 'Blue Danube');
INSERT INTO item (id, entry_date, name) VALUES(7, '2011-01-01', 'Schubert Sonata in B flat');
INSERT INTO item (id, entry_date, name) VALUES(8, '2011-01-01', 'Also Sprach Zarathrustra' );
-- ...
CREATE TABLE item_tag (id INT,
item_id INT REFERENCES tag(id),
name VARCHAR(32) );
-- INSERT INTO item_tag (id, item_id, name) VALUES () ....
QUERIES
为了简洁起见,我将描述一个单一的查询,它(希望)包含了我期望遇到的大多数用例场景。使用SQL实现下面的查询是微不足道的 - 使用mongrel,我不太清楚如何做到这一点:
回顾我的问题:
我熟悉Python和PHP - 所以使用PHP或Python API的解决方案会很棒(虽然我偏向于Python)。
答案 0 :(得分:2)
关于文档架构的好处是你不必从关系转换到它 - 你可以自己考虑它。考虑您将对该集合进行的查询,然后考虑如何使用您选择的语言处理数据。
我会考虑像每个文档代表一个项目的单个集合。每个项目都可以有一个名称,ID,条目日期,可能还有一个类别以及一系列标签。我也可以考虑将类别放入标签数组中,就像它是另一个标签一样。这取决于查询以及我将存储的项目的不同之处(食物和音乐可能需要单独的类别字段)。
如果您在自己的字段中保留类别,您的文档可能如下所示:
{
"_id" : 1,
"entry_date" : ISODate("2011-01-01T05:00:00Z"),
"title" : "A love supreme",
"category" : "music",
"tags" : [
"jazz",
"American"
]
}
如果您将它用作标记,它将是这样的:
{
"_id" : 1,
"entry_date" : ISODate("2011-01-01T05:00:00Z"),
"title" : "A love supreme",
"tags" : [
"music",
"American",
"jazz"
]
}
现在要查询你只需要find
组合你想要的条件。在第一种情况下:
db.items.find({entry_date:{$gt:new Date(2011,0,1)},
tags:{$in:["rap","classical"]}})
从技术上讲,如果您可能在电影或其他内容上添加这些标记,则可以添加category:"music"
。
在第二种情况下,它可能是:
db.items.find({entry_date:{$gt:new Date(2011,0,1)},
tags:"music",tags:{$in:["rap","classical"]}})
由于您可以在tags数组上使用multi-key indexes并且MongoDB支持compound indexes(如果您将按标签和entry_date进行常规查询),这将是一个非常有效的查询。