example with addFields
Closed this issue · 5 comments
I am trying to use addFields on my EsTC object, but the data comes up as empty object - could you provide an example of addFields in your documentation?
const ListingTypeComposer = composeWithElastic({
elasticClient,
elasticIndex,
elasticMapping,
elasticType,
graphqlTypeName,
})
ListingTypeComposer.addFields({
address: {
type: GraphQLString,
resolve: (source) => {
console.log('here is the source', source)
// above, source returns as {}
// even though data is coming back in my ListingTypeComposer.resolve
return source.addressLine1
}
},
})
If you could provide a working example in the readme of how addField can be used on top of graphql-compose-elasticsearch id really appreciate it
Try to modify needed Type inside Resolver:
// ListingTypeComposer.getResolver('search').getTypeComposer().getFieldTC('hits').addFields({
// shortand
ListingTypeComposer.get('$search.hits').addFields({
address: {
type: 'String', // <--- use short syntax, graphql-compose understood such things
resolve: (source) => {
console.log('here is the source', source)
// above, source returns as {}
// even though data is coming back in my ListingTypeComposer.resolve
return source.addressLine1
}
},
})
In this example we get search
resolver, then take its output type as TypeComposer object, then step down to hits
field (which will have elasticsearch row data) and modify this field type by addin to it address
field.
Thanks for the quick response. Ill try this out and update the issue if it works!
This is great @nodzk, this lets me do exactly what I want to. I'm wondering if you can help me with a more complex example
I want to resolve a field as 1 of 2 separate fields
import { ListingTypeComposer } from '../esListing'
const path = '$search.hits._source'
// https://graphql-compose.github.io/docs/en/api-TypeComposer.html
export const desktopPhone = {
type: 'String',
resolve: (
source: any,
args: { isSem?: boolean } = {},
) => {
return args.isSem
? source.semtollfree
: source.webtollfree
},
args: {
isSem: { type: 'Boolean' },
},
}
const customFields = {
desktopPhone,
}
export default ListingTypeComposer
.get(path)
.addFields(customFields)
.getResolver('search')
.getFieldConfig()
In the above example, I can query for desktop phone with the given query
query {
listing(listingId: "2016242") {
hits {
_source {
desktopPhone(isSem: true)
semtollfree < ----- id rather omit this and the next field
webtollfree
}
}
}
}
However, i'd like to be able to omit semtollfree
and webtollfree
from the query all together. Using graphql-compose, how can I fashion the request for desktopPhone to automatically resolve semtollfree and webtollfree in the source?
so I could end up doing something like this
query {
listing(listingId: "2016242") {
hits {
_source {
desktopPhone(isSem: true) <--- allows resolution of semtollfree and webtollfree
}
}
}
}
of course semtollfree and webtoll free exist in my es mapping where desktop phone does not
Just remove this fields from your type:
ListingTypeComposer.get('$search.hits').removeField(['semtollfree', 'webtollfree'])
How I remember elastic returns completely all fields for hits.source
. If it not happens (you will get empty data for your desktopPhone
field. You may try to use projection
property for requiring needed fields (request fields from db in programattic way if desktopPhone
field present in query):
export const desktopPhone = {
type: 'String',
resolve: (source: any, args: { isSem?: boolean } = {}) => {
return args.isSem
? source.semtollfree
: source.webtollfree
},
args: {
isSem: { type: 'Boolean' },
},
projection: {
semtollfree: true,
webtollfree: true,
}
}
Hope this will work.
@nodkz thank you so much for your work and your responses. they have been very helpful