django-elasticsearch-dsl-drf icon indicating copy to clipboard operation
django-elasticsearch-dsl-drf copied to clipboard

Apply functional boosting based on another field numerical value.

Open cyzanfar opened this issue 4 years ago • 0 comments

Questions

Hey!

I am trying to tune the relevance of my field search result based on another field numerical value (the field is in another model). Looking at the ES documentation it seems that functional boosts is what I need for my usecase.

My use case:

  1. I have a search field where users can search for companies based on the company name.
  2. I want to return the company names that match the query where sorting (relevance) depends on the company's net asset where the higher the value the more relevant (field in another model)

Model definition:

class Company(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255, blank=False, null=False)

    def __str__(self):
        return self.name

class CompanyNetAsset(models.Model):
    id = models.AutoField(primary_key=True)
    assets = models.IntegerField
    company_id = models.ForeignKey('Company', on_delete=models.PROTECT, blank=True, null=True)

    def __str__(self):
        return self.name

my es document:

...
custom_stop_words = token_filter(
    'custom_stopwords',
    type='stop',
    ignore_case=True,
    stopwords=['the', 'and']

)


html_strip = analyzer(
    'html_strip',
    tokenizer="standard",
    filter=["lowercase", "asciifolding", custom_stop_words],
    char_filter=["html_strip"],
)


@INDEX.doc_type
class CompanyDocument(Document):
    id = fields.IntegerField(attr='id')

    name = fields.TextField(
        analyzer=html_strip,
        fields={
            'raw': fields.TextField(analyzer='keyword'),
        }
    )

    class Django:
        model = Company

and here is the DocumentViewSet:

class CompanyDocumentViewSet(DocumentViewSet):
    """The Company Document view."""
    serializer_class = CompanyDocumentSerializer
    lookup_field = 'id'
    document = CompanyDocument
    filter_backends = [
        FilteringFilterBackend,
        SearchFilterBackend,
    ]
    search_fields = (
        'name'
    )

    filter_fields = {
        'id': None,
        'name': 'name.raw',

    }

Any suggestions on how to achieve this?

cyzanfar avatar Apr 08 '21 23:04 cyzanfar