graphql-compose-mongoose
graphql-compose-mongoose copied to clipboard
How to populate items in array?
I have in mongoose document collection with an array of documents:
export const DocumentsCollection = mongoose.model('Document-Collection',
new mongoose.Schema({
name: { type: String },
items: [
{
name: { type: String },
documents: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Document' }],
},
],
})
);
export const Document = mongoose.model( 'Document',
new mongoose.Schema(
{
name: { type: String },
description: { type: String }
},
{ timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' } }
)
);
I need to do a query that returns all the objects (findMany
) with items populated.
The problem is items returns as an array of mongoids.
How to extend the findMany
resolver to populate document object?
This is my expected query:
{
documentCollectionMany {
name,
items {
name
_id,
documents
}
}
}
Currently I getting this results:
{
"data": {
"documentCollectionMany": [
{
"name": "docgroup1",
"items": [
{
"name": "cat1",
"_id": "5ca37e1d21570b0011742473",
"documents": [
"5c6c0213f0fa853bd7d4a38c",
"5c6c02948e0004a16529a1a1",
"5c6c02ee7e76c62075850119",
"5c6ef2ddd16e17889ffaffd0"
]
}
]
}
]
}
}
@nodkz Is it something possible to do? because I can't find any working example.
https://graphql-compose.github.io/docs/basics/understanding-relations.html#relation-via-resolver
in your case it can look something like
DocumentCollectionTC.getFieldOTC('items').addRelation('documents', {
resolver: () => DocumentTC.getResolver('findByIds'),
prepareArgs: {
_ids: source => source.documents || [],
},
projection: { documents: true },
});
Thank you @nodkz ! I grateful for this package, and the solution to this topic. Maybe add this to the README ?! This helped me tremendously. It might help others.
https://graphql-compose.github.io/docs/basics/understanding-relations.html#relation-via-resolver
in your case it can look something like
DocumentCollectionTC.getFieldOTC('items').addRelation('documents', { resolver: () => DocumentTC.getResolver('findByIds'), prepareArgs: { _ids: source => source.documents || [], }, projection: { documents: true }, });
@nodkz
Is this still working for you? I'm finding that you can't populate a property that is of the same name as the array of ids. In this example the source of the ids is the documents
property which is also the very same property you intend to populate. I'm using this exact example to attempt to populate items on an array and it only works if I have a documentIds
array that I use as the _ids arguments source.
Does anyone know how to populate the same property?
@danimayfield Did you try to use dataloader?
DocumentCollectionTC.getFieldOTC('items').addRelation('documents', {
resolver: () => DocumentTC.mongooseResolvers.dataLoaderMany({ lean: true }),
prepareArgs: {
_ids: source => source.documents || [],
},
projection: { documents: true },
});
@danimayfield Did you try to use dataloader?
Yes I did, it turns out it's a discriminator issue and projection isn't working: https://github.com/graphql-compose/graphql-compose-mongoose/issues/441
Which is why I ended up needing two separate properties, one to hold the ids and one to hold the full documents created by the addRelation
for now