Home  >  Article  >  Database  >  标签云在MongoDB和go中的实现

标签云在MongoDB和go中的实现

WBOY
WBOYOriginal
2016-06-07 16:26:331302browse

在关系数据库如mysql中标签云的实现是显而易见的,标签和blog分别在不同的表中,通过join可以比较简单的查询出标签的统计数据。 MongoDB为快速水平扩张以及性能而优化,在MongoDB中没有join,倾向于使用embedding来代替linking关系: Generally, for "contai

在关系数据库如mysql中标签云的实现是显而易见的,标签和blog分别在不同的表中,通过join可以比较简单的查询出标签的统计数据。

MongoDB为快速水平扩张以及性能而优化,在MongoDB中没有join,倾向于使用embedding来代替linking关系:

Generally, for "contains" relationships between entities, embedding should be be chosen. Use linking when not using linking would result in duplication of data.

所以每个blog的标签应该是作为一个数组内嵌在blog记录中。那么就需要遍历所有的blog记录才能统计处所有tag的使用情况。 两种处理方式:

  1. 用一个额外的集合来保存tag的统计信息,所有涉及tag的操作都去更新这个集合。
  2. Schedule一个后台运行的job,定时运行mongodb的MapReduce操作来计算tag的使用数据。

第二种方式:

job := mgo.MapReduce {
        Map: "function(){if(!this.tags) return; for(i in this.tags){emit(this.tags[i],1);}}",
        Reduce: "function(key, values) {var sum = 0; for(i in values){sum = sum + values[i];} return sum;}",
        Out: bson.M{"replace":"tags"},
    }
    
    func CollectTags() {
        c := session.DB(DB).C("blog")
        _,err:= c.Find(nil).MapReduce(job, nil)
        if err!= nil {
            //TODO: better logger
            fmt.Println(err)
        }
    
        time.AfterFunc(MapReduceInterval, CollectTags)
    }
    
    func main() {
        go CollectTags()
        //Other...
    }
    

有了数据,tag云的生成就比较简单了,这里用的是wikipedia上介绍的计算公式: 公式

template:

{{if .}}
    <div class="tagcloud">
    {{range $tag, $size := .}}
        <a style="font-size: {{$size}}px; margin-right:5px;" href="http://chunhe.info/blogs/tags/%7B%7B%24tag%7D%7D">{{$tag}}</a>
    {{end}}
    </div>
    {{end}}
    

最大字体选择28,最终效果即如主页所示。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn