barseghyanartur / graphene-elastic

Graphene Elasticsearch/OpenSearch (DSL) integration
https://pypi.org/project/graphene-elastic/
71 stars 17 forks source link

How to handle foreign fields #65

Closed tanvir43 closed 2 years ago

tanvir43 commented 2 years ago

I want to show the foreign fields attributes in my search result, but i didn't get any clear instruction in the documentation.

models.py

class Product(models.Model):

product_name = models.CharField(max_length=100,  blank=True,  null=True)`
product_name_bn = models.CharField((max_length=100,  blank=True,  null=True)
product_unit = models.ForeignKey(
    ProductUnit, 
    on_delete=models.CASCADE, 
    default=None
)

i used django-elastic-dsl to create the document

documents.py

class ProductDocument(Document):

product_name = fields.TextField(
    fields = {
        'raw': {
            'type': 'text'
        }
    },
    analyzer = standard_analyzer
    )

product_name_bn = fields.TextField(
    fields = {
        'raw': {
            'type': 'text'
        }
    },
    analyzer= standard_analyzer
    )
product_unit = fields.ObjectField()
class Django(object):
    model = Product

queries.py

class ProductElasticNode(ElasticsearchObjectType):

class Meta:
    document = ProductDocument
    interfaces = (relay.Node,)
    filter_backends = [
        FilteringFilterBackend,
        SearchFilterBackend,
    ]
    filter_fields = {
        'product_name': {
            'field': 'product_name.raw',
            'lookups': [
                LOOKUP_FILTER_TERM,
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
            'default_lookup': LOOKUP_FILTER_TERM,
        },
        'product_name_bn': {
            'field': 'product_name_bn.raw',
            'lookups': [
                LOOKUP_FILTER_TERM,
                LOOKUP_FILTER_TERMS,
                LOOKUP_FILTER_PREFIX,
                LOOKUP_FILTER_WILDCARD,
                LOOKUP_QUERY_IN,
                LOOKUP_QUERY_EXCLUDE,
            ],
            'default_lookup': LOOKUP_FILTER_TERM,
        },
    }

    # For `SearchFilterBackend` backend
    search_fields = {
        'product_name': {'boost': '4'},
        'product_name_bn': {'boost': '4'}
    }

class Query(graphene.ObjectType): elastic_product = ElasticsearchConnectionField(ProductElasticNode)

query

query ProductElasticSearch{ elasticProduct( search: {query: "cola"} ){ edges{ node{ productName, productNameBn, productImage, productUnit } } } }

result

{ "data": { "elasticProduct": { "edges": [ { "node": { "productName": "Coca-Cola", "productNameBn": "Coca-Cola", "productImage": "/media/pictures/product/first.png", "productUnit": {} } }, ] } } }

can not select sub field of productUnit field. so the result is {}. If i do so, its raise following error

error

"Field \"productUnit\" of type \"ElasticJSONString\" must not have a sub selection."

tanvir43 commented 2 years ago

I am closing this issue as i have solved it by applying the following in my ProductDocument

... product_unit = fields.ObjectField(properties={ 'product_unit': fields.TextField(), })