在本教程中,我们将着眼于执行搜索操作以在MongoDB中检索文档。MongoDB 提供了一个find操作符来从集合中查询文档。find运算符的主要目的是根据查询条件从集合中选择文档,并将光标返回到所选文档。
在本教程中,我们将首先查看 MongoDB Shell 查询中的find运算符,然后使用 Java 驱动程序代码。
在我们继续执行查找操作之前,我们首先需要设置一个数据库baeldung和一个样本收集员工:
db.employee.insertMany([
{
"employeeId":"EMP1",
"name":"Sam",
"age":23,
"type":"Full Time",
"department":"Engineering"
},
{
"employeeId":"EMP2",
"name":"Tony",
"age":31,
"type":"Full Time",
"department":"Admin"
},
{
"employeeId":"EMP3",
"name":"Lisa",
"age":42,
"type":"Part Time",
"department":"Engineering"
}]);
成功插入后,上述查询将返回类似于下图所示的 JSON 结果:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("62a88223ff0a77909323a7fa"),
ObjectId("62a88223ff0a77909323a7fb"),
ObjectId("62a88223ff0a77909323a7fc")
]
}
此时,我们已将一些文档插入到我们的集合中以执行各种类型的查找操作。
要从 MongoDB 集合中查询文档,我们使用 db.collection.find(query, projection) 方法。该方法接受两个可选参数— 查询(query) 和 投影(projection) —作为 MongoDB BSON文档。
查询参数接受带有查询运算符的选择过滤器。要从 MongoDB 集合中检索所有文档,我们可以省略此参数或传递一个空白文档。
接下来,投影参数用于指定要从匹配文档返回的字段。要返回匹配文档中的所有字段,我们可以省略此参数。
此外,让我们从返回所有集合文档的基本查找查询开始:
db.employee.find({});
上面的查询将返回员工集合中的所有文档:
{ "_id" : ObjectId("62a88223ff0a77909323a7fa"), "employeeId" : "1", "name" : "Sam", "age" : 23, "type" : "Full Time", "department" : "Engineering" }
{ "_id" : ObjectId("62a88223ff0a77909323a7fb"), "employeeId" : "2", "name" : "Tony", "age" : 31, "type" : "Full Time", "department" : "Admin" }
{ "_id" : ObjectId("62a88223ff0a77909323a7fc"), "employeeId" : "3", "name" : "Ray", "age" : 42, "type" : "Part Time", "department" : "Engineering" }
*接下来,让我们编写一个查询来返回属于“Engineering” *部门的所有员工:
db.employee.find(
{
"department":"Engineering"
});
上述查询返回部门等于 “Engineering”的所有员工收款单据:
{ "_id" : ObjectId("62a88223ff0a77909323a7fa"), "employeeId" : "1", "name" : "Sam", "age" : 23, "type" : "Full Time", "department" : "Engineering" }
{ "_id" : ObjectId("62a88223ff0a77909323a7fc"), "employeeId" : "3", "name" : "Ray", "age" : 42, "type" : "Part Time", "department" : "Engineering" }
最后,让我们编写一个查询来获取属于“Engineering”部门的所有员工的 姓名 和 年龄:
db.employee.find(
{
"department":"Engineering"
},
{
"name":1,
"age":1
});
上述查询只返回符合查询条件的文档的名称和年龄字段:
{ "_id" : ObjectId("62a88223ff0a77909323a7fa"), "name" : "Sam", "age" : 23 }
{ "_id" : ObjectId("62a88223ff0a77909323a7fc"), "name" : "Ray", "age" : 42 }
请注意,除非明确排除,否则所有文档中默认返回_id字段。
此外,重要的是要注意 find 运算符将光标返回到与查询过滤器匹配的文档。MongoDB Shell 自动迭代光标以显示多达 20 个文档。
此外,MongoDB Shell 提供了一个*findOne()*方法,该方法只返回一个满足上述查询条件的文档。如果多个文档匹配,则将按照磁盘上文档的自然顺序返回第一个文档:
db.employee.findOne();
与*find()*不同,上面的查询将只返回一个文档而不是游标:
{
"_id" : ObjectId("62a99e22a849e1472c440bbf"),
"employeeId" : "EMP1",
"name" : "Sam",
"age" : 23,
"type" : "Full Time",
"department" : "Engineering"
}
到目前为止,我们已经了解了如何使用 MongoDB Shell 来执行查找操作。接下来,让我们使用 MongoDB Java 驱动程序实现相同的功能。在开始之前,让我们先创建一个到员工集合的MongoClient连接:
MongoClient mongoClient = new MongoClient("localhost", 27017);
MongoDatabase database = mongoClient.getDatabase("baeldung");
MongoCollection<Document> collection = database.getCollection("employee");
在这里,我们创建了到运行在默认端口 27017 上的 MongoDB 服务器的连接。接下来,我们从连接创建的*MongoDatabase实例中获取MongoCollection的实例。
首先,要执行*查找操作,我们在MongoCollection的实例上调用 find() 方法。让我们检查代码以从集合中检索所有文档:
FindIterable<Document> documents = collection.find();
MongoCursor<Document> cursor = documents.iterator();
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
请注意,find()方法返回FindIterable<Document>的一个实例。然后我们通过调用 FindIterable 的iterator()方法获得MongoCursor的一个实例。最后,我们遍历光标以检索每个文档。
接下来,让我们添加查询运算符来过滤从查找操作返回的文档:
Bson filter = Filters.eq("department", "Engineering");
FindIterable<Document> documents = collection.find(filter);
MongoCursor<Document> cursor = documents.iterator();
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
在这里,我们将Bson过滤器作为参数传递给find()方法。我们可以使用查询运算符的任意组合作为find()方法的过滤器。上面的代码片段将返回department 等于“Engineering”的所有文档。
此外,让我们编写一个片段,它只返回匹配选择条件的文档中的姓名和年龄字段:
Bson filter = Filters.eq("department", "Engineering");
Bson projection = Projections.fields(Projections.include("name", "age"));
FindIterable<Document> documents = collection.find(filter)
.projection(projection);
MongoCursor<Document> cursor = documents.iterator();
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
在这里,我们调用FindIterable实例的projection()方法。我们将Bson过滤器作为参数传递给*projection()*方法。我们可以使用投影操作在最终结果中包含或排除任何字段。
最后,我们可以使用FindIterable实例上的first()方法检索结果的第一个文档。这将返回单个文档而不是MongoCursor实例:
FindIterable<Document> documents = collection.find();
Document document = documents.first();
在本文中,我们学习了使用各种方法在 MongoDB 中执行查找操作。我们执行find以使用查询运算符检索与选择标准匹配的特定文档。此外,我们还学习了执行投影以确定匹配文档中返回的字段。
首先,我们研究了 MongoDB Shell 查询中find*操作的用例,然后讨论了相应的 Java 驱动程序代码。
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
有几种方法:first_or_create_by、find_or_create_by等,它们的工作原理是:与数据库对话以尝试找到我们想要的东西如果我们找不到,就自己做保存到数据库显然,并发调用这些方法可能会使两个线程都找不到它们想要的东西,并且在第3步中一个线程会意外失败。似乎更好的解决方案是,创建或查找即:提前在您的数据库中创建合理的唯一性约束。如果你想保存一些东西,就保存它如果有效,那就太好了。如果它因为RecordNotUnique异常而无法工作,它已经存在,太好了,加载它那么在什么情况下我想使用Rails内置的东西而不是我自己的(看起来更可靠)create_or_find?
我在Rails上使用带有ruby的solr。一切正常,我只需要知道是否有任何现有代码来清理用户输入,比如以?开头的查询。或* 最佳答案 我不知道执行此操作的任何代码,但理论上可以通过查看parsingcodeinLucene来完成并搜索thrownewParseException(只有16个匹配!)。在实践中,我认为您最好只捕获代码中的任何solr异常并显示“无效查询”消息或类似信息。编辑:这里有几个“sanitizer”:http://pivotallabs.com/users/zach/blog/articles/937-s
我正在为锦标赛开发一个Rails应用程序。我在这个查询中使用了三个模型:classPlayertruehas_and_belongs_to_many:tournamentsclassTournament:destroyclassPlayerMatch"Player",:foreign_key=>"player_one"belongs_to:player_two,:class_name=>"Player",:foreign_key=>"player_two"在tournaments_controller的显示操作中,我调用以下查询:Tournament.where(:id=>params
我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使
例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果
我目前正在尝试了解RoR。我将两个字符串传递到我的Controller中。一个是随机的十六进制字符串,另一个是电子邮件。该项目用于对数据库进行简单的电子邮件验证。我遇到的问题是当我输入如下内容来测试我的页面时:http://signup.testsite.local/confirm/da2fdbb49cf32c6848b0aba0f80fb78c/bob.villa@gmailcom我在:email的参数散列中得到的全部是'bob'。我在gmail和com之间留下了.,因为那样会导致匹配根本不起作用。我的路由匹配如下:match"confirm/:code/:email"=>"conf
我有一些模型需要在它们上面放置自定义查找条件。例如,如果我有一个联系人模型,每次调用Contact.find时,我都想限制返回的联系人只属于正在使用的帐户。我通过Google找到了这个(我对其进行了一些自定义):defself.find(*args)with_scope(:find=>{:conditions=>"account_id=#{$account.id}"})dosuper(*args)endend这很好用,除了少数情况下account_id不明确,所以我将其调整为:defself.find(*args)with_scope(:find=>{:conditions=>"#{s