user3888540
user3888540

Reputation: 105

mongoose query: find an object by id in an array

How could I find an image by id in this Schema. I have the id of the User and the id of the image I am looking for. What would be the best way to do this and do all images in this case have different ids or could they have the same id because they don't belong to the same User?

My Schema looks like this:

var userSchema = new Schema({
  local: {
    email: String,
    password: String
  },
  facebook: {
    id: String,
    token: String,
    email: String,
    name: String
  },
  name: String,
  about: String,
  images: [{
    id: Schema.ObjectId,
    link: String,
    main: Boolean
  }]
});

Upvotes: 9

Views: 24543

Answers (3)

PsiKai
PsiKai

Reputation: 1978

tl;dr

I struggled with this and came up with a solution. Like you, I was trying to query for a deeply nested object by the _id, but I kept coming up empty with the results. It wasn't until I did some type checking that I realized the id value I was getting from my frontend, while directly supplied by mongoose, was in fact a String and not an Object.

I realize this question was already partially answered before, but that person's solution didn't work for me, and the comment on the answer tells me you wanted to update the specific image you queried for, which is exactly what I was trying to do.

The solution

In order to select an object from the nested array by the _id value, first you'll have to install the npm package bson-objectid and use the provided method to convert your string into an objectId in your query.

In your terminal:

npm i bson-objectid

In your code:

const ObjectId = require('bson-objectid')

userSchema.findOneAndUpdate(
    { "facebook.id": <user-id>, "images._id": ObjectId(<image-id>) },
    { "$set": { "images.$.main": false } }, 
    { new: true }, // an extra options parameter that returns the mutated document
    (err, user) => {
        if (err) {
            handleErr(err)
        } else {
            console.log(user)
            // do something with new user info
        }
)

Upvotes: 0

adebasi
adebasi

Reputation: 3955

When you are interested in the full object it is a simple find:

.find({"facebook.id":"<id>", "images.id":<image-id>})

I don't think that there is a way to reduce the image array in the result.

To update a single element in the image array you can use this:

.update({"facebook.id":"<id>", "images.id":<image-id>}, {$set : {"images.$.main" :false} } );

Upvotes: 11

satish chennupati
satish chennupati

Reputation: 2650

userSchema .find({facebook.id: "some ID",{ "images.id": { $in: [ id1, id2, ...idn] }}

since images are inside the document you can have same ID's however every time you query you should keep in mind that you send some other parameters such as facebook.id or facebook.email along with image id's to retrieve them. Otherwise you end up getting all that might be irrelevant only because you decide to keep same ID's for images.

Upvotes: 2

Related Questions