【发布时间】:2014-05-13 17:55:39
【问题描述】:
我很确定我做错了什么。考虑以下代码:
criteria1 = Model.where(...)
criteria2 = Model.where(...)
results = (criteria1.to_a + criteria2.to_a)[offset..(offset + count_per_page - 1)]
此代码连接两个不同条件的结果,并获得具有给定偏移量(分页)的一定数量的结果。
此代码中的问题是隐含的。 to_a 方法调用实际上将条件的所有结果作为数组加载到内存中。
现在考虑一个非常庞大的集合...to_a 调用会大大减慢所有速度。
我想做的是这样的:
criteria1 = Model.where(...)
criteria2 = Model.where(...)
# A criteria, which returns results of the first criteria concatenated with results of the second criteria
criteria = criteria1 + criteria2
results = criteria.offset(offset).limit(count_per_page)
重要的是第二个标准的结果在第一个标准的结果之后。
任何线索如何用 Mongoid 实现?
谢谢!
更新
Gergo Erdosi 建议使用merge 方法。我尝试使用它,但它不是我想要的。这里的问题如下:
criteria1 = Model.where(:name => "John", :age => "23")
criteria2 = Model.where(:name => "Bob", :gender => "male")
criteria = criteria1.merge(criteria2)
p criteria.selector
# prints: { "name" => "Bob", :age => 23, :gender => "male" }
所以这里有两个问题:
-
merge不会产生 OR,它会用第二个查询覆盖第一个查询的公共键; - 即使我们使用
Model.or({ :name => "John" }, { :name => "Bob" })或Model.in(:name => ["John", "Bob"])结果也不会有正确的顺序。我希望第一个标准的结果首先出现,然后第二个标准的结果在之后。
有可能我有什么不明白的地方,Gergo 的回答是对的。你还有其他建议吗?谢谢。
更新 2
感谢 Gergo 在这里帮助我。让我们在 Mongo shell 中尝试一个简单的例子:
// Fill out test db with some simple documents.
for (var i = 0; i < 10; ++i) { db.users.insert({ name: i % 2 ? "John" : "Bob", age: Math.round(Math.random() * 100) }); }
// These queries give me the same order of documents.
db.users.find({ name: { $in: ["Bob", "John"] } });
db.users.find({ $or: [{ name: "Bob" }, { name: "John" }] });
// Like this:
{ "_id" : ObjectId("53732076b110ab9be7619a8e"), "name" : "Bob", "age" : 69 }
{ "_id" : ObjectId("53732076b110ab9be7619a8f"), "name" : "John", "age" : 63 }
{ "_id" : ObjectId("53732076b110ab9be7619a90"), "name" : "Bob", "age" : 25 }
{ "_id" : ObjectId("53732076b110ab9be7619a91"), "name" : "John", "age" : 72 }
// ...
// But I wish to get concatenated results of these queries:
db.users.find({ name: "Bob" });
db.users.find({ name: "John" });
// Like this (results of the first criteria go first):
{ "_id" : ObjectId("53732076b110ab9be7619a8e"), "name" : "Bob", "age" : 69 }
{ "_id" : ObjectId("53732076b110ab9be7619a90"), "name" : "Bob", "age" : 25 }
// ...
{ "_id" : ObjectId("53732076b110ab9be7619a8f"), "name" : "John", "age" : 63 }
{ "_id" : ObjectId("53732076b110ab9be7619a91"), "name" : "John", "age" : 72 }
// ...
请注意,我不能在这里使用简单的排序,因为实际应用程序中的数据更复杂。在实际应用中的标准如下所示:
// query variable is a string
exact_match_results = Model.where(:name => query)
inexact_match_results = Model.where(:name => /#{query}/i)
所以我们不能在这里按字母顺序排序。
【问题讨论】:
标签: ruby-on-rails ruby mongodb mongoid