Mongoose: `.lean()` don't include `id` after set `schema.option.id = true`

Created on 11 Sep 2015  路  10Comments  路  Source: Automattic/mongoose

Although I set Schema.option.id = true, model.find[One].lean() don't include id property. is that normal?

plugin

Most helpful comment

lean is really great, but many developers use id instead of _id. And now workaround can be like this:

Chart.find({ userId: userId }).lean()
    .then(charts => {
        if (charts.length) {
            return charts.map(chart => {
                chart.id = String(chart._id); // we add id explicitly
                return chart;
            });
        }

        return [];
    })
    .catch(err => {});

It's very annoying. It will be better to have maybe additional schema method leanWithId (or we can use new special option for lean):

Chart.find({ userId: userId }).leanWithId()
    .then(charts => {
        if (charts.length) {
            return charts;
        }

        return [];
    })
    .catch(err => {});

For example, mongoose-paginate plugin has leanWithId option for this purpose (https://github.com/edwardhotchkiss/mongoose-paginate#modelpaginatequery-options-callback).

All 10 comments

.lean() makes queries give you back a POJO, with no mongoose features. That means no virtuals, so no .id.

lean is really great, but many developers use id instead of _id. And now workaround can be like this:

Chart.find({ userId: userId }).lean()
    .then(charts => {
        if (charts.length) {
            return charts.map(chart => {
                chart.id = String(chart._id); // we add id explicitly
                return chart;
            });
        }

        return [];
    })
    .catch(err => {});

It's very annoying. It will be better to have maybe additional schema method leanWithId (or we can use new special option for lean):

Chart.find({ userId: userId }).leanWithId()
    .then(charts => {
        if (charts.length) {
            return charts;
        }

        return [];
    })
    .catch(err => {});

For example, mongoose-paginate plugin has leanWithId option for this purpose (https://github.com/edwardhotchkiss/mongoose-paginate#modelpaginatequery-options-callback).

I'd like to do this in a more general way than just .id, perhaps a withVirtuals option for lean()? Because tbh .id is an afterthought in mongoose and I've often thought of just deprecating it but decided against it. Just curious, why use .id instead of . _id?

withVirtuals will be very cool option :+1:

I actually never use _id. It's ok for small projects where you use only MongoDB, but if you develop large system with different services and different databases, the standard approach or maybe best practice is to name this field as id. So id is more universal name and does not rely on a specific technology. That's why I always recommend to use only id. And it's very easy with mongoose :smile:

Yeah personally I've never been a fan of _id either. Why on earth the ugly underscore was my first thought when I saw that, and I've been fighting with it ever since.

I use id in all client side code and have written Mongoose plugins to automatically convert _id to id in JSON for all schema's.

To me, _id just means two more unnecessary extra keystrokes and inconsistency :(

However, since working with Mongoose a lot I've grown more accustomed to seeing it, at least in server side code, but I'm still not happy about it ;)

+1 for universal naming and conventions.

A fair argument, I never really liked the _ myself. Worth mentioning that the id virtual isn't without its quirks though: it actually converts the object id to a string, which is what I don't like about it

So while working on the withVirtuals thing I realized that it would be much easier and cleaner to write a simple plugin for this. Use mongoose-lean-id, should work with any 4.x version of mongoose :+1: :rocket:

mongoose-lean-id plugin includes _id with id and when populate is used sub-documents don't include id only _id

@axmad22 can you please provide code samples? I'm not certain in my understanding of your comment, but it sounds like your issue is not attaching the mongoose-lean-id plugin to all your schemas, including the one for the model that you're populate()-ing

Just as a note for other devs using Graphql. Let's say you have Comment type, you can use lean and get comment's id by doing this inside resolver:

Comment: {
    id: parent => parent._id.toString(),
...
}
Was this page helpful?
0 / 5 - 0 ratings