Reputation: 309
Graphql returns null id for mongoose aggregation query, but works ok other mongoose queries.
Here is my mongoose schema:
const { Schema } = mongoose;
const ObjectId = Schema.Types.ObjectId;
const productSchema = new Schema({
_id: ObjectId,
price: Number
})
const Product = mongoose.model('Product', productSchema, 'Product')
Here is my Graphql schema:
type Product {
id: ID
price: String
}
Graphql normal query:
context.Product.findOne()
Result with console.log:
[ {
price: 10,
_id: 5d7f8efebff791dcd3bb1b69
}]
Result with graphql:
"getSearch": [
{
"id": "5d7f8efebff791dcd3bb1b69",
"price": 10,
}]
Everything is fine here. Now the problem is with aggregation query:
GraphQL query:
context.Product.aggregate(
[
{ $sample: { size: 1 } }
]
)
Result with console.log:
[ { _id: 5d7f8f23bff791dcd3bb1da3,
price: 5
}]
Result with GraphQL:
"test": [
{
"id": null",
"price": 7,
}]
The problem here is:
Upvotes: 5
Views: 1845
Reputation: 501
Adding id
element to the result works fine to mine
const res = await Product.aggregate(
[
{ $sample: { size: 1 } }
]
)
res.forEach(element => {
element.id = element._id
});
return res;
Upvotes: 1
Reputation: 1286
If you are using mongoose with nest js
and GraphQL
, I have fixed it by changing the id
to _id
and removing the @prop
above it Example on github
@Prop()//remove this
@Field(() => ID,{ nullable: true })
_id: string;
Upvotes: 0
Reputation: 458
Just add both IDs if you don't want to change every single instance of it.
type Product {
id: ID
_id: ID
price: String
}
Upvotes: 0
Reputation: 84657
Documents in MongoDB normally don't have an id
property, just an _id
property. This is shown in the console output you're seeing. However, mongoose model instances do have a getter for id
that returns the value of id
. From the docs:
Mongoose assigns each of your schemas an id virtual getter by default which returns the documents _id field cast to a string, or in the case of ObjectIds, its hexString.
What's returned by methods like find
and findOne
are instances of the Model that have this getter. However, using aggregate
results in plain JavaScript objects being returned instead (with no getter).
You can write a resolver for the id
field to pull the value from either id
or _id
:
function resolve (parent, args, context, info) {
return parent.id || parent._id
}
Upvotes: 4