MVC View News计数器和Google Analytics之间存在巨大差异

时间:2017-04-10 11:13:13

标签: asp.net-mvc google-analytics

我有一个计数器,用于计算视图的显示次数:

public class News
{
    [Key]
    public int Id { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DatePostedOn { get; set; }
    public DateTime DateModified { get; set; }  
    public string Title { get; set; }
    public string Description { get; set; }
    public string Meta { get; set; }
    public string UrlSlug { get; set; }
    public bool Popular { get; set; }
    public int Position { get; set; }
    public int Views { get; set; }         // <---- COUNTER
}

每次加载页面时,我都会看到+1:

public virtual ActionResult Detail(string urlSlug)
{
    News news = db.News
                    .Include("Category")
                    .Where(n => n.UrlSlug.Equals(urlSlug))
                    .FirstOrDefault();

    NewsDetailVM vm = Mapper.Map<News, NewsDetailVM>(news);

    vm.RelatedNews = db.News
                        .Where(r => r.Category.Id == news.Category.Id)
                        .Where(r => r.Hidden == false)
                        .Where(r => r.Id != news.Id)
                        .OrderByDescending(r => r.DateCreated)
                        .Take(3)
                        .Select(r => new NewsRelatedVM()
                        {
                            Title = r.Title,
                            Date = r.DateCreated,
                            UrlSlug = r.UrlSlug,
                            CategoryName = r.Category.Name,
                            CategoryURLSlug = r.Category.UrlSlug,
                            PictureURL = r.Pictures.Where(p => p.Type == 2).FirstOrDefault().Filename
                        })
                        .ToList();

    vm.CategoriesList = db.Categories
                        .Where(c => c.Channel == 1)
                        .Project().To<NewsListCategoryItemVM>()
                        .ToList();

    news.Views = news.Views + 1;    // <-- COUNTER UPDATE

    db.SaveChanges();

    return View(vm);
}

问题在于,例如在星期六,当天发布的新闻有6464,Google分析为新闻控制器提供了2359次综合浏览量。

从哪里出现这种差异?我在柜台上做错了吗?

3 个答案:

答案 0 :(得分:7)

几乎不可能说出这种差异的确切原因是什么,但也有一些可能的罪魁祸首。首先,GA可能会忽略机器人,特别是GoogleBot。但是,您的方法并不会将机器人索引到您的网站。例如,每次GoogleBot点击此视图时,它都会在数据库中递增,但不会在GA中递增。您需要通过蜘蛛将此视图排除在访问之外,或者找一些方法来过滤掉机器人的请求。

其次,GA可能会过滤掉重复的匹配。例如,假设用户登陆视图,然后点击刷新按钮50次。您的数据库计数增加了50倍,但GA可能仍将其视为单个网页浏览。一般情况下,您应该通过记录REMOTE_IP来限制您的计数器,并且只有在该IP在一段时间内(例如15分钟)没有访问该页面时才会增加。然后,你至少不会记录每次刷新。

最后,在这种情况下,计数将始终处于关闭状态,因为并非每个客户端都支持或启用了JavaScript(意味着GA无法跟踪这些客户端),并且客户端的隐私设置也可能会阻止GA跟踪。然而,无论您是否愿意,此数据库计数都将计算每个请求。

答案 1 :(得分:3)

您不能依赖Entity Framework来更新这样的计数器,因为它会将最新值提取到内存中,在内存中更改它,然后将其保存到数据库中。

如果有多个人同时点击你的动作方法,那么他们每个人都可以将相同的值增加1并将其保存回数据库。在更新数据库时,您需要对数据库中的值执行锁定。

或者允许数据库执行它最擅长的操作,即管理更新 像这样,您可以通过使用存储过程来实现这一点,例如我刚刚在下面编写的那个:

CREATE PROCEDURE usp_increment_count (@newsId int)

  UPDATE dbo.News SET Views = Views + 1 WHERE id = @newsId 
  GO

然后使用实体框架从代码中调用该过程:

SqlParameter newsId = new SqlParameter("@newsId", news.Id);
db.Database.ExecuteSqlCommand("usp_increment_count @newsId", newsId);

我希望这会有所帮助。

答案 2 :(得分:2)

计数不是完全相同的,也不是100%准确。

如果有并发访问,您的实体框架代码将不起作用。见Concurrency with EF。本文向您展示了如何修改表和程序以使计数准确。具有存储过程的解决方案看起来可以与您的示例一起使用,但不是一般解决方案,因为除非在存储过程中完成所有更改,否则它也将失败。这在EF6中更容易。

Google Analytics(分析)有一系列问题。有很多文章提供详细信息,这里是sample article。不要在客户端代码中折扣编码问题。

您可能考虑的解决方案是创建一个新表来跟踪访问。这很容易解决EF并发问题。新表行至少包含主键和新闻Id列。只需在每次读取时添加一个新行。然后使用单独的查询访问计数,使用适当的索引,这应该足够快。这种方法的优点是您可以添加额外的信息,如访问时间,访问来源以及协调或证明您的计数所需的任何其他信息。

您可能尝试帮助解决问题的另一件事是分析Web服务器日志。有很多选项,维基百科是一个很好的起点,搜索“网络服务器日志分析”。同样,这些测量的东西略有不同,并且会给出不同的计数。