sca*_*ble 10 python django json django-haystack elasticsearch
我有一些看起来如下的JSON:让我们调用该字段元数据
{
"somekey1": "val1",
"someotherkey2": "val2",
"more_data": {
"contains_more": [
{
"foo": "val5",
"bar": "val6"
},
{
"foo": "val66",
"baz": "val44"
},
],
"even_more": {
"foz" : 1234,
}
}
}
Run Code Online (Sandbox Code Playgroud)
这只是一个简单的例子.真正的人可以变得更加复杂.钥匙可以多次出现.值也可以是int或str.
现在第一个问题是我不太确定如何在elasticsearch中对此进行正确索引,以便我可以找到具有特定请求的内容.
我正在使用Django/Haystack,索引如下所示:
class FooIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
metadata = indexes.CharField(model_attr='get_metadata')
# and some more specific fields
Run Code Online (Sandbox Code Playgroud)
和模板:
{
"foo": {{ object.foo }},
"metadata": {{ object.metadata}},
# and some more
}
Run Code Online (Sandbox Code Playgroud)
然后将使用上面的示例填充元数据,结果将如下所示:
{
"foo": "someValue",
"metadata": {
"somekey1": "val1",
"someotherkey2": "val2",
"more_data": {
"contains_more": [
{
"foo": "val5",
"bar": "val6"
},
{
"foo": "val66",
"baz": "val44"
},
],
"even_more": {
"foz" : 1234,
}
}
},
}
Run Code Online (Sandbox Code Playgroud)
这将进入elasticsearch的'text'列.
因此,现在的目标是能够搜索以下内容:
第二个问题:当我搜索例如foo:val5时,它匹配所有具有键"foo"的对象以及在其结构中具有val5的所有对象.
这是我在Django中搜索的方式:
self.searchqueryset.auto_query(self.cleaned_data['q'])
Run Code Online (Sandbox Code Playgroud)
有时结果是"好的",有时它完全没用.
我可能需要一个正确方向的指针,并了解我在这里犯的错误.谢谢!
编辑:我在下面添加了我的最终解决方案作为答案!
我花了一段时间才找到适合我的正确解决方案
它混合了@juliendangers和@Val提供的答案以及一些更多的自定义内容。
get_type_mapping向模型添加自定义方法
@classmethod
def get_type_mapping(cls):
return {
"properties": {
"somekey": {
"type": "<specific_type>",
"format": "<specific_format>",
},
"more_data": {
"type": "nested",
"include_in_parent": True,
"properties": {
"even_more": {
"type": "nested",
"include_in_parent": True,
}
/* and so on for each level you care about */
}
}
}
Run Code Online (Sandbox Code Playgroud)get_document向模型添加自定义方法
@classmethod
def get_document(cls, obj):
return {
'somekey': obj.somekey,
'more_data': obj.more_data,
/* and so on */
}
Run Code Online (Sandbox Code Playgroud)添加自定义搜索表单
class Searchform(ElasticsearchForm):
q = forms.Charfield(required=False)
def get_index(self):
return 'your_index'
def get_type(self):
return 'your_model'
def prepare_query(self):
if not self.cleaned_data['q']:
q = "*"
else:
q = str(self.cleaned_data['q'])
return {
"query": {
"query_string": {
"query": q
}
}
}
def search(self):
esp = ElasticsearchProcessor(self.es)
esp.add_search(self.prepare_query, page=1, page_size=25, index=self.get_index(), doc_type=self.get_type())
responses = esp.search()
return responses[0]
Run Code Online (Sandbox Code Playgroud)所以这对我有用并涵盖了我的用例。也许这对某人有帮助。
| 归档时间: |
|
| 查看次数: |
2041 次 |
| 最近记录: |