我想在我的Node.js应用程序中实现一个分类结构(地理术语),并使用NoSQL数据库。我之前使用MySQL有一个类似的分类结构,但是现在是时候前进学习新方法了,所以我决定尝试不同的方法,并在测试应用程序中使用NoSQL(面向文档)。分类结构很简单-共有五个不同的级别:国家(例如英国)→地区(英格兰)→县(默西塞德郡)→城市/镇/村庄(利物浦)→城市一部分(托克斯特)。
显而易见的选择是使用树形结构,但问题在于细节-历史上有些城市和城镇属于其他县。这样做的目的是为了给出生于某些城市或城镇的人打上标签,并在以后通过地理标签进行过滤,因此我必须尊重利物浦或曼彻斯特(以及其他一些城市)当时是兰开夏郡的一部分,这样任何用户通过我的地理过滤器得到的结果就不会有误。
例如:John Doe于1957年出生于兰开郡的布莱克本。 Paul Brown于1960年在利物浦(兰开夏,现在是默西塞德)出生。Georgia Doe(原名Jones)5年后在威勒(切谢尔,现在是默西塞德)出生。他们的儿子Ringo于1982年在利物浦(那时是默西塞德)出生。John出生于兰开夏,Paul是兰开夏人和默西塞德人,Georgia同时来自切谢尔和默西塞德,Ringo来自默西塞德。因此,当我按县搜索时,他们应该被相应地分类。但是使用现代国家的简单一对多的结构,他们永远不会被正确过滤。
如何使用NoSQL(首先是面向文档的)解决方案实现这个复杂结构的集合?我在Google上搜索并在stack*上进行了一些研究,但仍然不知道下一步该怎么做。在我看来,有几种可能的解决方法:
- 使用类似SQL的数据结构:
{ {'name': 'United Kingdom', 'unique_id': 1}, {'name': 'England', 'unique_id': 2, 'parents': [1]}, {'name': 'Merseyside', 'unique_id': 3, 'parents': [2]}, {'name': 'Lancashire', 'unique_id': 4, 'parents': [2]}, {'name': 'Liverpool', 'unique_id': 5, 'parents': [3, 4]}, }
使用带有一些引用的树形结构:
{ {'name': 'United Kingdom', 'unique_id': 1 {'name': 'England', 'unique_id': 2] {'name': 'Merseyside', 'unique_id': 3] {'name': 'Liverpool', 'unique_id': 5, 'alternate_parents': [4]}, }, {'name': 'Lancashire', 'unique_id': 4}, }, }, }
使用树形结构,不要使用参考(一对多),并手动为文档添加“备用父级”标签:
坚持使用SQL。
- 尝试实现无数据库的分类法。
{
{'name': 'United Kingdom', 'unique_id': 1
{'name': 'England', 'unique_id': 2]
{'name': 'Merseyside', 'unique_id': 3]
{'name': 'Liverpool', 'unique_id': 5},
},
{'name': 'Lancashire', 'unique_id': 4},
},
},
}
请给我在这个问题上提点建议。我对任何NoSQL都是新手(目前没有设计此类数据库),所以这对我来说确实是一个设计问题。
而且我对stack*也是新手,如果我在这篇文章中做错了什么,请随时纠正我:) 谢谢!
编辑 我选择了@Jonathan的答案作为解决方案。我认为它更适合我的需求(将有其他文档存储在我的数据库中,并使用这些术语对它们进行标记),特别是@Valentyn建议的mapReduce功能。
但是,如果你的应用程序不需要文档集合,那么@Philipp建议的基于关系而非文档的图形数据库可能是最佳解决方案。