短版本:我需要从Posts
集合中获得一个与/web/
或任何其他术语匹配的不同标签数组。
我对实现MapReduce模式来提供";自动完成";领域你认为这是最好的方法吗?
我的Posts
收藏有以下文档:
{
'title': 'A great post',
'tags': ['web2.0', 'monetize', 'cloud', 'someOtherDumbTerm']
}
{
'title': 'Another great post',
'tags': ['monetize', 'seo-optimization', 'web3.0']
}
给定像/web/
这样的搜索,我会得到这样的结果:["web2.0", "web3.0"]
我的MapReduce函数如下:
var mapFn = function(){
if( this.tags ){
this.tags.forEach(function(value){
if (value.match(/web/i)){
emit('web', value);
}
});
}
};
var reduceFn = function(key, values){
return {result:values};
};
db.runCommand({
mapreduce: 'posts',
out: {inline:1},
map: mapFn,
reduce: reduceFn,
query: {tags:/web/}
});
我正在考虑将标签存储在不同的集合中,并定期搜索它们,但我似乎发现了多年RDBMS学习留下的残余直觉。我也不知道这类查询的性能或其他含义,文档对这种情况似乎没有太大用处。
谢谢!
我最终做了什么
实际上,我最终只是使用MapReduce来分析上述标签。
我按照描述的方式将它们存储在不同的集合中,并将其规范化为正则表达式搜索的基本ASCII(即没有重音符号等),同时保留原始术语。然后,我将tag
对象id引用到另一个集合中的post
id。
所有这些我都变成了一个不同的应用程序来服务不同的客户。事实证明,这是满足我特殊需求的最佳解决方案。
我认为将标记映射/减少到不同的集合听起来非常合理。
您无法实时运行Map/Reduce查询。而且,您不能使用标准的"查找"查询从现有集合中仅获取所需的标记。你可能不在乎你的标签自动完成系统是否不包括最后一小时或最后一天的新标签,或者你的MapReduce作业运行的频率如何。