ChatGPT解决这个技术问题 Extra ChatGPT

How to select a single field for all documents in a MongoDB collection?

In my MongoDB, I have a student collection with 10 records having fields name and roll. One record of this collection is:

{
    "_id" : ObjectId("53d9feff55d6b4dd1171dd9e"),
    "name" : "Swati",
    "roll" : "80",
}

I want to retrieve the field roll only for all 10 records in the collection as we would do in traditional database by using:

SELECT roll FROM student

I went through many blogs but all are resulting in a query which must have WHERE clause in it, for example:

db.students.find({ "roll": { $gt: 70 })

The query is equivalent to:

SELECT * FROM student WHERE roll > 70

My requirement is to find a single key only without any condition. So, what is the query operation for that.

@NeilLunn Thanks for the link SQL to MongoDB Mapping. Don't know how I missed this.
Today is my first day in MongoDB, I didn't digest the point ,why 1 is mandatory in db.student.find({},{roll:1}) ,Why it is not designed in a way like this db.student.find({},{roll}) . Any situation we are giving any other value than 1
@Arun because it's json formart, i think.
@ShipraSwati it would be great for future references if you accept an answer to the question.

t
therealrootuser

From the MongoDB docs:

A projection can explicitly include several fields. In the following operation, find() method returns all documents that match the query. In the result set, only the item and qty fields and, by default, the _id field return in the matching documents. db.inventory.find( { type: 'food' }, { item: 1, qty: 1 } )

In this example from the folks at Mongo, the returned documents will contain only the fields of item, qty, and _id.

Thus, you should be able to issue a statement such as:

db.students.find({}, {roll:1, _id:0})

The above statement will select all documents in the students collection, and the returned document will return only the roll field (and exclude the _id).

If we don't mention _id:0 the fields returned will be roll and _id. The '_id' field is always displayed by default. So we need to explicitly mention _id:0 along with roll.


Can't seem to Google this, so worth a shot. Do you have to explicitly exclude all the fields that you don't want? Say you only want one field but the document has 10 you have to explictly set 0 for 9 of them? Edit: Nevermind, excluding _id i.e. {field_I_want:1, _id:0} seems to work
Is it possible to add a field and then update the doc if I use projections?
None of the answers actually mentions the following: Note: With the exception of the _id field, you cannot combine inclusion and exclusion statements in projection documents. This might be interesting for some of you. (source)
If anyone has problems getting this to work it might be because you are running a newer version of the mongodb driver which has changed the API slightly: db.students.find({}, { projection : { roll:1, _id:0 } }) You now have to specify the fields you want to include/exclude on the projection key. Documentation: mongodb.github.io/node-mongodb-native/3.0/api/…
N
Naman

get all data from table

db.student.find({})

SELECT * FROM student

get all data from table without _id

db.student.find({}, {_id:0})

SELECT name, roll FROM student

get all data from one field with _id

db.student.find({}, {roll:1})

SELECT id, roll FROM student

get all data from one field without _id

db.student.find({}, {roll:1, _id:0})

SELECT roll FROM student

find specified data using where clause

db.student.find({roll: 80})

SELECT * FROM students WHERE roll = '80'

find a data using where clause and greater than condition

db.student.find({ "roll": { $gt: 70 }}) // $gt is greater than 

SELECT * FROM student WHERE roll > '70'

find a data using where clause and greater than or equal to condition

db.student.find({ "roll": { $gte: 70 }}) // $gte is greater than or equal

SELECT * FROM student WHERE roll >= '70'

find a data using where clause and less than or equal to condition

db.student.find({ "roll": { $lte: 70 }}) // $lte is less than or equal

SELECT * FROM student WHERE roll <= '70'

find a data using where clause and less than to condition

db.student.find({ "roll": { $lt: 70 }})  // $lt is less than

SELECT * FROM student WHERE roll < '70'


Just wanted to add, since your answer helped me figure out my solution, to display all properties except _id would be db.student.find({}, {_id:0}) Thanks for the help.
getting error when excluding id " cannot do exclusion on field in inclusion projection "
T
Throvn

I think mattingly890 has the correct answer , here is another example along with the pattern/commmand

db.collection.find( {}, {your_key:1, _id:0})

> db.mycollection.find().pretty();

{
    "_id": ObjectId("54ffca63cea5644e7cda8e1a"),
    "host": "google",
    "ip": "1.1.192.1"
}
db.mycollection.find({},{ "_id": 0, "host": 1 }).pretty();

to show the output from mongo and what it returns as an example.
Dude did you give me a down vote because I had included screenshot in my answer ?
Yes, and also because i don't see what your answer brings new from @therealrootuser 's anwer
V
Vivek Doshi

Here you go , 3 ways of doing , Shortest to boring :

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

To remove specific field use - operator :

db.student.find({}).select('roll -_id') // <--- Will remove id from result

I think your mentioned commands are from mongoose and not mongodb except 3rd one.
S
Smily

While gowtham's answer is complete, it is worth noting that those commands may differ from on API to another (for those not using mongo's shell).
Please refer to documentation link for detailed info.

Nodejs, for instance, have a method called `projection that you would append to your find function in order to project.

Following the same example set, commands like the following can be used with Node:

db.student.find({}).project({roll:1})

SELECT _id, roll FROM student

Or
db.student.find({}).project({roll:1, _id: 0})

SELECT roll FROM student

and so on.

Again for nodejs users, do not forget (what you should already be familiar with if you used this API before) to use toArray in order to append your .then command.


K
Karan Khanna

Try the following query:

db.student.find({}, {roll: 1, _id: 0});

And if you are using console you can add pretty() for making it easy to read.

db.student.find({}, {roll: 1, _id: 0}).pretty();

Hope this helps!!


pretty() will only be useful when executing via shell, not from scripts.
V
Vaggelis Stefanakis

Just for educational purposes you could also do it with any of the following ways:

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);

`


A
Anthony Awuley
db.<collection>.find({}, {field1: <value>, field2: <value> ...})

In your example, you can do something like:

db.students.find({}, {"roll":true, "_id":false})

Projection

The projection parameter determines which fields are returned in the matching documents. The projection parameter takes a document of the following form:

{ field1: <value>, field2: <value> ... }

The can be any of the following: 1 or true to include the field in the return documents. 0 or false to exclude the field.

NOTE

For the _id field, you do not have to explicitly specify _id: 1 to return the _id field. The find() method always returns the _id field unless you specify _id: 0 to suppress the field.

READ MORE


H
Hasib Kamal Chowdhury

For better understanding I have written similar MySQL query.

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';


A
Aishwarya Panchal

This works for me,

db.student.find({},{"roll":1})

no condition in where clause i.e., inside first curly braces. inside next curly braces: list of projection field names to be needed in the result and 1 indicates particular field is the part of the query result


P
PrabhuPrakash

getting name of the student

student-details = db.students.find({{ "roll": {$gt: 70} },{"name": 1, "_id": False})

getting name & roll of the student

student-details = db.students.find({{ "roll": {$gt: 70}},{"name": 1,"roll":1,"_id": False})

s
samsri

I just want to add to the answers that if you want to display a field that is nested in another object, you can use the following syntax

db.collection.find( {}, {{'object.key': true}})

Here key is present inside the object named object

{ "_id" : ObjectId("5d2ef0702385"), "object" : { "key" : "value" } }


r
rohit mali
 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);
        });
      });  

it's working


ρ
ρяσѕρєя K

Use the Query like this in the shell:

1. Use database_name

e.g: use database_name

2. Which returns only assets particular field information when matched , _id:0 specifies not to display ID in the result

db.collection_name.find( { "Search_Field": "value" }, 
                  { "Field_to_display": 1,_id:0 }  )

B
Biju Maharjan

If u want to retrieve the field "roll" only for all 10 records in the collections. Then try this.

In MongoDb :

db.students.find( { } , { " roll " : { " $roll " })

In Sql :

select roll from students


A
Ankit Kumar Rajpoot

The query for MongoDB here fees is collection and description is a field.

db.getCollection('fees').find({},{description:1,_id:0})

G
Gandalf the White

Apart from what people have already mentioned I am just introducing indexes to the mix.

So imagine a large collection, with let's say over 1 million documents and you have to run a query like this.

The WiredTiger Internal cache will have to keep all that data in the cache if you have to run this query on it, if not that data will be fed into the WT Internal Cache either from FS Cache or Disk before the retrieval from DB is done (in batches if being called for from a driver connected to database & given that 1 million documents are not returned in 1 go, cursor comes into play)

Covered query can be an alternative. Copying the text from docs directly.

When an index covers a query, MongoDB can both match the query conditions and return the results using only the index keys; i.e. MongoDB does not need to examine documents from the collection to return the results.

When an index covers a query, the explain result has an IXSCAN stage that is not a descendant of a FETCH stage, and in the executionStats, the totalDocsExamined is 0.

Query :  db.getCollection('qaa').find({roll_no : {$gte : 0}},{_id : 0, roll_no : 1})

Index : db.getCollection('qaa').createIndex({roll_no : 1})

If the index here is in WT Internal Cache then it would be a straight forward process to get the values. An index has impact on the write performance of the system thus this would make more sense if the reads are a plenty compared to the writes.


G
General Grievance

If you are using the MongoDB driver in NodeJs then the above-mentioned answers might not work for you. You will have to do something like this to get only selected properties as a response.

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);

This code is copied from the actual MongoDB doc you can check here. https://docs.mongodb.com/drivers/node/current/usage-examples/findOne/


R
Rito
db.student.find({}, {"roll":1, "_id":0})

This is equivalent to -

Select roll from student

db.student.find({}, {"roll":1, "name":1, "_id":0})

This is equivalent to -

Select roll, name from student


P
Pulla

In mongodb 3.4 we can use below logic, i am not sure about previous versions

select roll from student ==> db.student.find(!{}, {roll:1})

the above logic helps to define some columns (if they are less)


j
j3ff

Using Studio 3T for MongoDB, if I use .find({}, { _id: 0, roll: true }) it still return an array of objects with an empty _id property.

Using JavaScript map helped me to only retrieve the desired roll property as an array of string:

var rolls = db.student
  .find({ roll: { $gt: 70 } }) // query where role > 70
  .map(x => x.roll);           // return an array of role

A
AshishTheThinker

Not sure this answers the question but I believe it's worth mentioning here. There is one more way for selecting single field (and not multiple) using db.collection_name.distinct();

e.g.,db.student.distinct('roll',{});

Or, 2nd way: Using db.collection_name.find().forEach(); (multiple fields can be selected here by concatenation)

e.g., db.collection_name.find().forEach(function(c1){print(c1.roll);});


N
Neo Murphy

_id = "123321"; _user = await likes.find({liker_id: _id},{liked_id:"$liked_id"}); ; let suppose you have liker_id and liked_id field in the document so by putting "$liked_id" it will return _id and liked_id only.


s
shikha singh

For Single Update : db.collection_name.update({ field_name_1: ("value")}, { $set: { field_name_2 : "new_value" }});

For MultiUpdate : db.collection_name.updateMany({ field_name_1: ("value")}, { $set: {field_name_2 : "new_value" }});

Make sure indexes are proper.