[英]Django DRF elastic search dsl, Apply functional boosting based on another field numerical value
我正在嘗試根據另一個字段數值(該字段在另一個模型中)調整我的字段搜索結果的相關性。 查看ES 文檔,我的用例似乎需要功能提升。
請注意,我使用的是django-elasticsearch-dsl ; package。
我的用例:
Model定義:
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
我的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
這是 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',
}
知道如何使用 drf ES package 實現這一目標嗎?
更新
這是一個示例查詢:
/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"
},
...
而這里是一個子 output 的文檔:
{'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'}}}}
ES 不支持查詢時連接,因此您需要在Company
model 中復制CompanyNetAsset
屬性,以便能夠讓assets
影響您的排序。
實際上,像這樣調整Company
model:
class Company(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, blank=False, null=False)
assets = models.IntegerField
def __str__(self):
return self.name
然后調整Document
:
@INDEX.doc_type
class CompanyDocument(Document):
id = fields.IntegerField(attr='id')
name = fields.TextField(
analyzer=html_strip,
fields={
'raw': fields.TextField(analyzer='keyword'),
}
)
assets = fields.IntegerField(attr='assets')
class Django:
model = Company
最后,重新索引您的文檔並定義排序:
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',
}
# Define ordering fields # <--
ordering_fields = {
'assets': None
}
# Specify default ordering
ordering = ('assets')
要通過 URI 強制排序,請運行:
GET /api/v1/employers/companies/?search=name:foundation%20center&ordering=-assets
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.