最开始对付项目列表中的每个项目的成果数量,采用查询数据库,循环去查,因为一个项目下面有4~6层目录,每一层为几十个目录,这样一个项目下大概有4800个目录,每个目录下有成百上千的成果。
这样一个树状项目目录表category,
id parentid
和对应的成果表product。
id categoryid
试了一下,30个项目情况下,成果数量为0,仅项目列表显示要花2s。
页面中的项目列表要反应每个项目下的成果。如果成百上千个项目,然后每个项目下4800个目录,要查询每个目录下的成果数量……
因为:要么循环查询数据库,要么把所有项目目录category表一次性查出来(15.6万),把所有成果product表一次性查出来(beego orm默认只会查出1000个结果来),再循环——递归。
func (c *ProjController) GetProjects() {
id := c.Ctx.Input.Param(":id")
if id == "" {
//显示全部
projects, err := models.GetProjects()
if err != nil {
beego.Error(err)
}
categories, err := models.GetAllProjects()
if err != nil {
beego.Error(err)
}
products, err := models.GetAllProducts()
if err != nil {
beego.Error(err)
}
//取得每个项目的成果数量
projects1 := make([]Project1, 0) //这里不能加*号
for _, v := range projects {
aa := make([]Project1, 1)
aa[0].Id = v.Id
aa[0].Code = v.Code
aa[0].Title = v.Title
aa[0].Label = v.Label
aa[0].Principal = v.Principal
//取得项目所有成果——速度太慢
//修改为一次性取到所有成过,然后循环赋值给aa
//取项目本身
// category, err := models.GetProj(v.Id)
// if err != nil {
// beego.Error(err)
// }
//取项目所有子孙——这样效率太低
// categories, err := models.GetProjectsbyPid(v.Id)
// if err != nil {
// beego.Error(err)
// }
//根据项目id取得项目下所有成果
//——效率太低
// products, err := models.GetProjProducts(v.Id)
// if err != nil {
// beego.Error(err)
// }
var count int
for _, m := range products {
if v.Id == m.ProjectId {
count = count + 1
}
}
slice := getsons(v.Id, categories)
// 如果遍历的当前节点下还有子节点,则进入该子节点进行递归
if len(slice) > 0 {
getprodcount(slice, categories, products, &count)
}
aa[0].Number = count //len(products)
aa[0].Created = v.Created
aa[0].Updated = v.Updated
projects1 = append(projects1, aa...)
}
c.Data["json"] = projects1
c.ServeJSON()
} else {
//根据标签查询
}
}
改进:
将数据库目录表category增加一个字段,每个项目的子目录都带有这个项目的id,这样一次性查出这个项目的所有目录(相当于加了一个索引)。
id parentid projectid
再改进一下成果表,将成果表增加一个字段,除了目录id外,增加一个项目id,这样一次性查出这个项目的所有成果和成果数量(相当于加了一个索引)。
id categoryid projectid
接下来,就是树状目录显示成果数量的问题了,每个子目录都要显示这个目录下所有成果数量。
树状目录采用懒加载,一次只加载一层。但是这一层还是要计算出所有下级成果数量。还是采用递归。