Elasticsearch multi-requêtes / recherche avec Python
Je suis nouveau dans Python et Elasticsearch et j'ai créé un index avec des données dans Elasticsearch et je souhaite effectuer une requête sur eux avec Python en fonction de certains filtres reçus de l'utilisateur (mot-clé, catégorie)
from elasticsearch import Elasticsearch
import json,requests
es = Elasticsearch(HOST="http://localhost", PORT=9200)
es = Elasticsearch()
def QueryMaker (keyword,category):
response = es.search(index="main-news-test-data",body={"from":0,"size":10000,"query":{
"bool": {
"should": [
{
"multi_match" : {
"query": keyword,
"fields": [ "content", "title","lead" ]
}
},
{
"multi_match" : {
"query": category,
"fields": [ "category" ]
}
}
]
}
}})
return(response)
def Mapper (category):
fhandle = open('categories.txt','r', encoding="utf8")
for line in fhandle:
line = line.rstrip()
items = line.split(';')
if f'"{category}"' in items:
category = items[0]
return(category)
if __name__ == '__main__':
keyword = input('Enter Keyword: ')
print(type(keyword))
category = input('Enter Category: ')
print(type(category))
#startDate = input('Enter StartDate: ')
#endDate = input('Enter EndDate: ')
mapCategory = Mapper(category)
if mapCategory is not None:
mapCategory = mapCategory.replace("%","")
data = QueryMaker(keyword,mapCategory)
print(data)
else:
data = QueryMaker(keyword,mapCategory)
print(data)
Le problème est que ce programme ne renvoie les données correspondantes que si les 2 champs sont pleins, mais je veux qu'il renvoie également des données si 1 champ comme catégorie est vide. Lorsque le mot-clé est vide, c'est comme '' et il ne renvoie rien et lorsque la catégorie est vide, je reçois cette erreur:
elasticsearch.exceptions.RequestError: RequestError(400, 'x_content_parse_exception', '[multi_match] unknown token [VALUE_NULL] after [query]')
Qu'est-ce que je fais de mal et comment puis-je corriger mon filtre de recherche?
Réponses
Ajout d'un exemple fonctionnel avec des données d'index, une requête de recherche et un résultat de recherche
Selon vos commentaires mentionnés ci-dessus, si le contentchamp ne contient pas keyword, et si le categorychamp contient category, la requête de recherche s'exécutera pour le categorychamp. Ceci peut être réalisé en utilisantminimum_should_match
Données d'index:
{
"content": "keyword a",
"title": "b",
"lead": "c",
"category": "d"
}
{
"content": "a",
"title": "b",
"lead": "c",
"category": "category"
}
{
"content": "keyword a",
"title": "b",
"lead": "c",
"category": "category"
}
Requête de recherche:
{
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "keyword",
"fields": [
"content",
"title",
"lead"
]
}
},
{
"multi_match": {
"query": "category",
"fields": [
"category"
]
}
}
],
"minimum_should_match":1
}
}
}
Résultat de la recherche:
"hits": [
{
"_index": "stof_64081587",
"_type": "_doc",
"_id": "3",
"_score": 0.9666445,
"_source": {
"content": "keyword a",
"title": "b",
"lead": "c",
"category": "category"
}
},
{
"_index": "stof_64081587",
"_type": "_doc",
"_id": "2",
"_score": 0.60996956,
"_source": {
"content": "keyword a",
"title": "b",
"lead": "c",
"category": "d"
}
},
{
"_index": "stof_64081587",
"_type": "_doc",
"_id": "1",
"_score": 0.35667494,
"_source": {
"content": "a",
"title": "b",
"lead": "c",
"category": "category"
}
}
]