将用户的行为历史存储到MongoDB中
我在开发Rails应用程序,有一个需求是要显示用户的使用历史记录等内容。
我想要保存用户逐一浏览的页面和更新等信息。
我们的数据库使用MySQL,但是将行为历史等信息存储到关系型数据库中可能会对性能造成一些担忧,而且这些数据也不会被删除,会不断地积累下来,所以我想到了将其放入键值存储。
所以,我尝试了一下。
环境 –
自然界和人类活动所包围的周围条件、空气、水、土地的状态。
-
- MacOSX Lion
-
- Ruby 2.0
- Rails 4.0
安装MongoDB
如果要在我的MacOS上安装MongoDB,请参考这篇文章。如果要安装在外部服务器上,请点击这里的文章。
安装CentOS上的MongoDB并设置允许外部连接。
在 MacOS 上安装时,请使用 Homebrew。
brew install mongodb
# インストール完了後のメッセージに従って、以下のコマンドを実行
ln -sfv /usr/local/opt/mongodb/*.plist ~/Library/LaunchAgents
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
mongo --version
=> MongoDB shell version: 2.6.4
使用Rails应用程序更新MongoDB数据库
添加一个用于MongoDB的gem到Rails中。
如果不安装bson_ext,后面的”config.mongoid.logger”会出现undefined method错误。
gem "mongoid"
gem "bson_ext"
安装
bundle install --path .bundle
创建配置文件,保持内容不变即可。
rails g mongoid:config
=>create config/mongoid.yml
定义保存设置模型
如果默认的DB是关系数据库(RDB),要生成与MongoDB连接的model,可以按照以下方式进行。
rails g mongoid:model action_log
修改模型,并定义所需的字段。
class ActionLog
include Mongoid::Document
field :datetime, type: DateTime
field :user_id, type: String
field :user_name, type: String
field :controller, type: String
field :method, type: String
field :body, type: String
field :delete, type: Boolean
end
使用MongoDB就不需要執行db:migrate,真是太開心了。
立刻進行更新試試看。
首先從Rails控制台進行測試。
irb(main):002:0> ActionLog.create!(datetime:Time.now, user_id:0, user_name:"jacoyutorius", body:"test")
=> #<ActionLog _id: 543df2987975746196000000, datetime: 2014-10-15 04:05:43 UTC, user_id: "0", user_name: "jacoyutorius", controller: nil, method: nil, body: "test", delete: nil>
我能成功更新事务。
我想要记录用户的每个操作。
好的。回想起最初的规格,起初的要求是“想要获取用户的行为历史!”。这次我们打算通过将控制器的每个动作调用时的参数和登录用户保存到MongoDB中来解决这个问题。
由于在每个控制器中重复编写相同代码不符合DRY(Don’t Repeat Yourself)原则,因此我们可以使用concerns进行处理。
module LogMonger
extend ActiveSupport::Concern
included do
before_action :save_log
def save_log
ActionLog.create!(
datetime: Time.now,
user_id: 1,
user_name: "jacoyutorius",
method: params[:method],
controller: params[:controller],
body: params,
delete: false
)
end
end
end
所有通过控制器传递过来的参数都被全部存储在请求主体中。
然后在每个控制器中进行包含操作。
class UsersController < ApplicationController
include LogMonger
# -(省略)-
end
现在启动Rails应用程序,尝试随意更改一下。
在MongoDB中保存的样子是这样的。
irb(main):005:0> ActionLog.first
=> #<ActionLog _id: 543deed77975745d73000000, datetime: 2014-10-15 03:49:43 UTC, user_id: "1", user_name: "jacoyutorius", controller: "admin/top", method: nil, body: "{\"controller\"=>\"top\", \"action\"=>\"index\"}", delete: false>
我做到了!
(2014年10月17日添加)
使用了ActiveRecord和Mongoid两个库。当在ActiveRecord中运行migration命令时,会出现”错误 mongoid [not found]”的错误。在这种情况下,应该
rails g active_record:migration AddHoge
当你明确指定使用ActiveRecord时,可以创建迁移。我通过参考这篇文章解决了问题。
当Mongoid和ActiveRecord并存的情况下迁移的处理方式
(进一步添加)
根据上述的处理方式,使用scaffold时也会使用同样的mongoid。最好在application.rb中定义好generator的设置。
class Application < Rails::Application
config.generators do |g|
g.orm :active_record
end
end
参考—仅需要一种选择,原生地用中文言简意赅地改述以下内容:
“MongoDB坏实践集”
虽然有一些不良经验,但如果使用方法专注于特定的用途(例如本例中的日志记录),我认为就没有问题了。