如何为 MongoDB 集合中的所有文档选择单个字段?
Posted
技术标签:
【中文标题】如何为 MongoDB 集合中的所有文档选择单个字段?【英文标题】:How to select a single field for all documents in a MongoDB collection? 【发布时间】:2014-10-24 16:41:24 【问题描述】:在我的 MongoDB 中,我有一个包含 10 条记录的学生集合,其中包含字段 name
和 roll
。该集合的一条记录是:
"_id" : ObjectId("53d9feff55d6b4dd1171dd9e"),
"name" : "Swati",
"roll" : "80",
我想只为集合中的所有 10 条记录检索字段 roll
,就像我们在传统数据库中使用的那样:
SELECT roll FROM student
我浏览了很多博客,但都导致查询中必须包含WHERE
子句,例如:
db.students.find( "roll": $gt: 70 )
查询相当于:
SELECT * FROM student WHERE roll > 70
我的要求是只找到一个没有任何条件的键。那么,查询操作是什么。
【问题讨论】:
@NeilLunn 感谢SQL to MongoDB Mapping 的链接。不知道我是怎么错过的。 今天是我在 MongoDB 的第一天,我没有理解重点,为什么1
在 db.student.find(,roll:1)
中是强制性的,为什么它不是这样设计的 db.student.find(,roll)
。除了1
,我们提供的任何其他值
@Arun 因为它是 json 格式,我想。
@ShipraSwati 如果您接受该问题的答案,它将非常适合将来参考。
【参考方案1】:
如果您在 NodeJs 中使用 MongoDB 驱动程序,那么上述答案可能不适合您。您必须执行类似的操作才能仅获取选定的属性作为响应。
import MongoClient from "mongodb";
// Replace the uri string with your MongoDB deployment's connection string.
const uri = "<connection string uri>";
const client = new MongoClient(uri);
async function run()
try
await client.connect();
const database = client.db("sample_mflix");
const movies = database.collection("movies");
// Query for a movie that has the title 'The Room'
const query = title: "The Room" ;
const options =
// sort matched documents in descending order by rating
sort: "imdb.rating": -1 ,
// Include only the `title` and `imdb` fields in the returned document
projection: _id: 0, title: 1, imdb: 1 ,
;
const movie = await movies.findOne(query, options);
/** since this method returns the matched document, not a cursor,
* print it directly
*/
console.log(movie);
finally
await client.close();
run().catch(console.dir);
此代码复制自您可以在此处查看的实际 MongoDB 文档。 https://docs.mongodb.com/drivers/node/current/usage-examples/findOne/
【讨论】:
【参考方案2】:尝试以下查询:
db.student.find(, roll: 1, _id: 0);
如果您使用控制台,您可以添加 pretty() 使其易于阅读。
db.student.find(, roll: 1, _id: 0).pretty();
希望这会有所帮助!
【讨论】:
pretty() 仅在通过 shell 执行时有用,而不是从脚本执行。【参考方案3】:除了人们已经提到的之外,我只是在混合中引入索引。
想象一个大型集合,假设有超过 100 万个文档,您必须运行这样的查询。
如果您必须对其运行此查询,WiredTiger 内部缓存必须将所有数据保留在缓存中,否则,数据将在从数据库检索之前从 FS 缓存或磁盘馈送到 WT 内部缓存已完成(如果从连接到数据库的驱动程序中批量调用,并且考虑到 1 百万个文档未在 1 次中返回,则光标开始发挥作用)
覆盖查询可以是一种替代方法。直接从docs复制文字。
当索引覆盖查询时,MongoDB既可以匹配查询条件,也可以仅使用索引键返回结果;即 MongoDB 不需要检查集合中的文档来返回结果。
当索引覆盖查询时,解释结果有一个不是 FETCH 阶段后代的 IXSCAN 阶段,并且在 executionStats 中,totalDocsExamined 为 0。
Query : db.getCollection('qaa').find(roll_no : $gte : 0,_id : 0, roll_no : 1)
Index : db.getCollection('qaa').createIndex(roll_no : 1)
如果此处的索引位于 WT 内部缓存中,那么获取值将是一个直接的过程。索引对系统的写入性能有影响,因此如果读取比写入多,这将更有意义。
【讨论】:
【参考方案4】:来自MongoDB docs:
一个投影可以显式包含多个字段。在下面的操作中,
find()
方法返回所有匹配查询的文档。在结果集中,只有 item 和 qty 字段以及默认情况下 _id 字段在匹配的文档中返回。
db.inventory.find( type: 'food' , item: 1, qty: 1 )
在这个来自 Mongo 的示例中,返回的文档将仅包含 item
、qty
和 _id
的字段。
因此,您应该能够发出如下声明:
db.students.find(, roll:1, _id:0)
上述语句会选择学生集合中的所有文档,返回的文档将只返回roll
字段(并排除_id
)。
如果我们不提及_id:0
,则返回的字段将是roll
和_id
。默认情况下始终显示“_id”字段。所以我们需要明确提及_id:0
和roll
。
【讨论】:
Google 似乎无法搜索此内容,因此值得一试。您是否必须明确排除所有不需要的字段?假设您只想要一个字段,但文档有 10 个字段,您必须为其中的 9 个明确设置0
?编辑:没关系,不包括_id
即field_I_want:1, _id:0
似乎工作
如果我使用投影,是否可以添加一个字段然后更新文档?
没有一个答案实际上提到以下内容:注意:With the exception of the _id field, you cannot combine inclusion and exclusion statements in projection documents.
这对你们中的一些人来说可能很有趣。 (source)
如果有人在让它工作时遇到问题,可能是因为你运行的是新版本的 mongodb 驱动程序,它稍微改变了 API:db.students.find(, projection : roll:1, _id:0 )
你现在必须指定你想要的字段在projection
键上包含/排除。文档:mongodb.github.io/node-mongodb-native/3.0/api/…【参考方案5】:
从表中获取所有数据
db.student.find()
从学生中选择 *
从没有_id的表中获取所有数据
db.student.find(, _id:0)
选择姓名,从学生处滚动
使用_id从一个字段中获取所有数据
db.student.find(, roll:1)
SELECT id, roll FROM student
从一个不带 _id 的字段中获取所有数据
db.student.find(, roll:1, _id:0)
从学生中选择卷
使用 where 子句查找指定数据
db.student.find(roll: 80)
SELECT * FROM students WHERE roll = '80'
使用 where 子句和大于条件查找数据
db.student.find( "roll": $gt: 70 ) // $gt is greater than
SELECT * FROM student WHERE roll > '70'
使用where子句且大于等于条件查找数据
db.student.find( "roll": $gte: 70 ) // $gte is greater than or equal
SELECT * FROM student WHERE roll >= '70'
使用 where 子句和小于等于条件查找数据
db.student.find( "roll": $lte: 70 ) // $lte is less than or equal
SELECT * FROM student WHERE roll
使用 where 子句和小于条件查找数据
db.student.find( "roll": $lt: 70 ) // $lt is less than
SELECT * FROM student WHERE roll
【讨论】:
只是想补充一下,因为您的回答帮助我找出了我的解决方案,显示所有属性 except _id 将是db.student.find(, _id:0)
感谢您的帮助。
排除 id 时出现错误“无法对包含投影中的字段进行排除”【参考方案6】:
var collection = db.collection('appuser');
collection.aggregate(
$project : firstName : 1, lastName : 1 ,function(err, res)
res.toArray(function(err, realRes)
console.log("response roo==>",realRes);
);
);
工作正常
【讨论】:
【参考方案7】:_id = "123321"; _user = await likes.find(liker_id: _id,liked_id:"$liked_id"); ;
假设您在文档中有liker_id 和liked_id 字段,因此通过输入“$liked_id”,它将只返回_id 和liked_id。
【讨论】:
【参考方案8】:不确定这是否能回答问题,但我认为这里值得一提。
还有另一种方法可以使用 db.collection_name.distinct();
选择单个字段(而不是多个字段)
例如,db.student.distinct('roll',);
或者,第二种方式:使用db.collection_name.find().forEach();
(这里可以通过串联选择多个字段)
例如,db.collection_name.find().forEach(function(c1)print(c1.roll););
【讨论】:
【参考方案9】:这里查询MongoDB的费用是收款,描述是一个字段。
db.getCollection('fees').find(,description:1,_id:0)
【讨论】:
【参考方案10】:将 Studio 3T 用于 MongoDB,如果我使用 .find(, _id: 0, roll: true )
,它仍会返回具有空 _id
属性的对象数组。
使用 javascript map
帮助我只检索所需的 roll
属性作为字符串数组:
var rolls = db.student
.find( roll: $gt: 70 ) // query where role > 70
.map(x => x.roll); // return an array of role
【讨论】:
【参考方案11】:我只是想补充一下,如果要显示嵌套在另一个对象中的字段,可以使用以下语法
db.collection.find( , 'object.key': true)
这里的 key 存在于名为 object 的对象中
"_id" : ObjectId("5d2ef0702385"), "object" : "key" : "value"
【讨论】:
【参考方案12】:虽然gowtham's answer 已完成,但值得注意的是,这些命令可能与 API 上的命令不同(对于那些不使用 mongo shell 的命令)。 详情请参考documentation link。
例如,Nodejs 有一个名为 `projection 的方法,您可以将其附加到 find 函数中以便进行投影。
按照相同的示例集,Node 可以使用如下命令:
db.student.find().project(roll:1)
选择 _id,从学生处滚动
或者db.student.find().project(roll:1, _id: 0)
从学生中选择卷
等等。
再次提醒 nodejs 用户,不要忘记(如果您之前使用过此 API,您应该已经熟悉)使用 toArray
来附加您的 .then
命令。
【讨论】:
【参考方案13】:db.<collection>.find(, field1: <value>, field2: <value> ...)
在您的示例中,您可以执行以下操作:
db.students.find(, "roll":true, "_id":false)
投影
projection 参数决定了在 匹配的文件。投影参数需要一个文档 如下形式:
field1: <value>, field2: <value> ...
The <value> can be any of the following:
1 或 true 以在返回文档中包含该字段。
0 或 false 以排除该字段。
注意
对于 _id 字段,您不必显式指定 _id: 1 即可 返回 _id 字段。 find() 方法总是返回 _id 字段 除非您指定 _id: 0 来禁止该字段。
READ MORE
【讨论】:
【参考方案14】:给你,3种做事方式,最短的无聊:
db.student.find(, 'roll _id'); // <--- Just multiple fields name space separated
// OR
db.student.find().select('roll _id'); // <--- Just multiple fields name space separated
// OR
db.student.find(, 'roll' : 1 , '_id' : 1 ); // <---- Old lengthy boring way
要删除特定字段使用-
运算符:
db.student.find().select('roll -_id') // <--- Will remove id from result
【讨论】:
我认为你提到的命令来自猫鼬而不是 mongodb,除了第三个。【参考方案15】:为了更好地理解,我编写了类似的 MySQL 查询。
Selecting specific fields
MongoDB: db.collection_name.find(,name:true,email:true,phone:true);
MySQL : SELECT name,email,phone FROM table_name;
Selecting specific fields with where clause
MongoDB: db.collection_name.find(email:'you@email.com',name:true,email:true,phone:true);
MySQL : SELECT name,email,phone FROM table_name WHERE email = 'you@email.com';
【讨论】:
【参考方案16】:如果您只想检索集合中所有 10 条记录的字段“roll”。 那就试试这个吧。
在 MongoDb 中:
db.students.find( , "roll" : "$roll" )
在 Sql 中:
从学生中选择卷
【讨论】:
【参考方案17】:这对我有用,
db.student.find(,"roll":1)
where 子句中没有条件,即在第一个花括号内。 在下一个大括号内:结果中需要的投影字段名称列表,1 表示特定字段是查询结果的一部分
【讨论】:
【参考方案18】:在 mongodb 3.4 中我们可以使用以下逻辑,我不确定以前的版本
从学生中选择卷 ==> db.student.find(!, roll:1)
上述逻辑有助于定义一些列(如果它们更少)
【讨论】:
【参考方案19】:在 shell 中使用这样的查询:
1.使用database_name
e.g: use database_name
2.匹配时只返回资产特定字段信息,_id:0
指定在结果中不显示ID
db.collection_name.find( "Search_Field": "value" ,
"Field_to_display": 1,_id:0 )
【讨论】:
【参考方案20】:获取学生姓名
student-details = db.students.find( "roll": $gt: 70 ,"name": 1, "_id": False)
获取学生的姓名和名册
student-details = db.students.find( "roll": $gt: 70,"name": 1,"roll":1,"_id": False)
【讨论】:
【参考方案21】:db.student.find(, "roll":1, "_id":0)
这相当于 -
从学生中选择卷
db.student.find(, "roll":1, "name":1, "_id":0)
这相当于 -
选择卷,学生姓名
【讨论】:
【参考方案22】:仅出于教育目的,您也可以通过以下任何一种方式进行:
1.
var query = "roll": $gt: 70;
var cursor = db.student.find(query);
cursor.project("roll":1, "_id":0);
2.
var query = "roll": $gt: 70;
var projection = "roll":1, "_id":0;
var cursor = db.student.find(query,projection);
`
【讨论】:
【参考方案23】:我认为 mattingly890 有正确的答案,这是另一个示例以及模式/命令
db.collection.find( , your_key:1, _id:0)
【讨论】:
以显示 mongo 的输出及其返回的内容为例。 老兄,你给我投了反对票,因为我在回答中包含了屏幕截图吗? 是的,也是因为我没有看到你的答案从@therealrootuser 的回答中带来了什么新的东西以上是关于如何为 MongoDB 集合中的所有文档选择单个字段?的主要内容,如果未能解决你的问题,请参考以下文章