0

我有一个用 Mongoid 编写的查询

@result = User.find(:name=>"xxxxx").limit(5) 

我将 json 中的数据返回为

render :json =>@result.to_json() 

现在我想将名称为xxxxx的用户总数添加到@result变量中。我尝试了几件事,但没有任何效果

@new_result ={:result =>@result, :count=>@result.length} 

render :json =>@new_result.to_json() 

输出是

[{new_result:null,count:25}] 

基本上我能够得到计数,但我无法将该计数添加到我的@result。有没有办法让这个工作。

4

1 回答 1

1

温馨提示:

All queries in Mongoid are Criteria, which is a chainable and lazily evaluated wrapper to a MongoDB dynamic query.

请参阅: http: //mongoid.org/en/mongoid/docs/querying.html#query_plus

请务必了解 Mongoid Criteria 是惰性评估的,否则会导致您感到困惑并花费您的时间,并且会花费更多时间...

当我运行你的@result = User.find(:name=>"xxxxx").limit(5) 时,我得到一个 Mongoid::Errors::DocumentNotFound 异常,这是 Mongoid 2.4.10。你确定你的问题是准确的吗?

我已将其更改为 User.where,@result = User.find(:name=>"xxxxx").limit(5) 是一个 Criteria,而不是(尚未)从 MongoDB 读取的 User 实例。

下面的测试应该有助于明确由于延迟评估,DB 查询仅在需要时发生,例如,在方法 to_json 和方法长度之后。此外,跟踪您的日志,并注意每次使用带有 to_json 或 length 方法的 @result 都会导致重复的数据库查询,这是低效的,可能不是您想要的。您可以使用 Enumerable#to_a 或 Enumerable#each 等方法强制进行评估和获取。

测试/单元/user_test.db

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  def setup
    User.delete_all
  end

  test "mongoid lazy eval" do
    User.create(name: 'xxxxx')
    assert_equal(1, User.count)
    puts "User.all.to_a: #{User.all.to_a.inspect}"
    assert_raises Mongoid::Errors::DocumentNotFound do
      @result = User.find(:name=>"xxxxx").limit(5)
    end
    puts "@result = User.find(:name=>\"xxxxx\").limit(5); @result: #{@result.inspect}"
    @result = User.where(:name=>"xxxxx").limit(5)
    puts "@result = User.where(:name=>\"xxxxx\").limit(5); @result.class: #{@result.class}"
    puts "@result.to_json: #{@result.to_json}"
    puts "@result.length: #{@result.length}"
    @new_result ={:result =>@result, :count=>@result.length}
    puts "@new_result: #{@new_result.inspect}"
    puts "@new_result.to_json: #{@new_result.to_json}"
  end
end

测试输出

Run options: --name=test_mongoid_lazy_eval

# Running tests:

User.all.to_a: [#<User _id: 4fca03e7e4d30b1e42000001, _type: nil, name: "xxxxx">]
@result = User.find(:name=>"xxxxx").limit(5); @result: nil
@result = User.where(:name=>"xxxxx").limit(5); @result.class: Mongoid::Criteria
@result.to_json: [{"_id":"4fca03e7e4d30b1e42000001","name":"xxxxx"}]
@result.length: 1
@new_result: {:result=>#<Mongoid::Criteria
  selector: {:name=>"xxxxx"},
  options:  {:limit=>5},
  class:    User,
  embedded: false>
, :count=>1}
@new_result.to_json: {"result":[{"_id":"4fca03e7e4d30b1e42000001","name":"xxxxx"}],"count":1}
.

Finished tests in 0.038161s, 26.2048 tests/s, 52.4095 assertions/s.

1 tests, 2 assertions, 0 failures, 0 errors, 0 skips
于 2012-06-02T12:29:31.080 回答