J'essaie d'ajuster la pertinence du résultat de la recherche d'un champ en fonction de la valeur numérique d'un autre champ (le champ se trouve dans un autre modèle). En regardant le Documentation ES il semble que stimulations fonctionnelles est ce dont j'ai besoin pour mon cas d'utilisation.
Notez que j'utilise le django-elasticsearch-dsl ; paquet.
Mon cas d'utilisation :
- J'ai un champ de recherche dans lequel les utilisateurs peuvent rechercher des entreprises sur la base du nom de l'entreprise.
- Je veux renvoyer les noms de sociétés qui correspondent à la requête où le tri (pertinence) dépend de l'actif net de la société, où plus le nombre est élevé, plus il est pertinent (champ dans un autre modèle).
Définition du modèle :
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
mon document es :
...
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
et voici le 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',
}
Une idée de la façon dont je peux y parvenir en utilisant le paquet drf ES ?
UPDATE
Voici un exemple de requête :
/api/v1/employers/companies/?search=name:foundation%20center
"results": [
{
"id": 469329,
"name": "THE FOUNDATION CENTER",
"city": "NEW YORK",
"state": "NY"
},
{
"id": 323012,
"name": "OVERTURE CENTER FOUNDATION",
"city": "MADISON",
"state": "WI"
},
{
"id": 367286,
"name": "PEACE CENTER FOUNDATION",
"city": "GREENVILLE",
"state": "SC"
},
...
Et voici une sortie fils du document :
{'settings': {'number_of_shards': 1,
'number_of_replicas': 1,
'analysis': {'analyzer': {'html_strip': {'tokenizer': 'standard',
'filter': ['lowercase', 'asciifolding', 'custom_stopwords'],
'char_filter': ['html_strip'],
'type': 'custom'}},
'filter': {'custom_stopwords': {'ignore_case': True,
'stopwords': ['the', 'and'],
'type': 'stop'}}}},
'mappings': {'properties': {'id': {'type': 'integer'},
'city': {'type': 'text'},
'state': {'type': 'text'},
'name': {'analyzer': 'html_strip',
'fields': {'raw': {'analyzer': 'keyword', 'type': 'text'}},
'type': 'text'}}}}