14/04/22 - 16h30

master
ChérifBALDE 2022-04-14 16:14:57 +02:00 committed by cherif
parent 16d54640c1
commit 699bf5f3f9
7 changed files with 523 additions and 12 deletions

View File

@ -458,3 +458,95 @@ def test_ela_myntlk():
my_file.close()
'''
def ela_index_article_avis_record_field(lines, article_avis_id, source_field = ""):
try:
'''
## Suppression de toutes les indexation qui existe de cette formation
'''
client = MongoClient(CONNECTION_STRING)
dbname = client['cherifdb']
coll_name = dbname['elaindex_article_avis']
# check default value of parameter : source_field
if len(str(source_field)) == 0 :
source_field = 'default'
myquery = {"id_articles_avis": article_avis_id, "source_field":source_field}
delete_row = coll_name.delete_many(myquery)
mycommon.myprint(" elaindex Article AVIS : - "+str(delete_row.deleted_count)+" documents deleted. Article_Avis ==> "+str(article_avis_id)+" ")
'''
Ajout des indexe
'''
tab_tokens = Ela_Tokenize(lines)
tab_tokens2 = Ela_remove_stop_words(tab_tokens)
tab_tokens3 = Ela_remove_pronoun(tab_tokens2)
tab_tokens4 = Ela_stemmize(tab_tokens3)
tab_tokens4 = Ela_Remove_Noise_from_list(tab_tokens4)
tab_tokens4 = Ela_remove_ponct(tab_tokens4)
# Enregistrement dans la base mongodb
Ela_article_avis_list_to_mongo(tab_tokens4, article_avis_id, source_field)
size_tab = len(tab_tokens4)
occurrences = Counter(tab_tokens4)
most_common = occurrences.most_common()
print(most_common)
return True
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False
def Ela_article_avis_list_to_mongo(tab_tokens, traning_id, source_field):
try:
# clear / truncate elaindex
#db.elaindex.remove({})
# Recherche des occurence d'une valeur
my_file = open("ela_output_article_file_pandas_2.txt", "w")
size_tab = len(tab_tokens)
occurrences = Counter(tab_tokens)
# insert the list to the set
list_set = set(tab_tokens)
# convert the set to the list
unique_list = (list(list_set))
final_lists = []
for tmp in unique_list:
moyenne = round(int(occurrences[str(tmp)]) / size_tab, 2)
final_lists.append([str(tmp), int(str(occurrences[str(tmp)])), str(moyenne), str(traning_id), str(source_field)])
print(final_lists)
data = pd.DataFrame(final_lists, columns=('mots', "occurence", 'moyenne', 'id_article_avis', 'source_field'))
my_file.write(str(data))
my_file.close()
# Making a Connection with MongoClient
client = MongoClient("mongodb://localhost:27017/")
# database
db = client["cherifdb"]
# collection
collection = db["elaindex_article_avis"]
data.reset_index(inplace=True)
data_dict = data.to_dict("records")
# Insert collection
collection.insert_many(data_dict)
data.to_csv("data_indexees_article_avis.csv")
return True
except Exception as e :
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False

View File

@ -280,7 +280,6 @@ def add_articles_avis(diction):
my_user_recid = user_recid
print(" ########### RECID = "+user_recid)
mydata['user_recid'] = my_user_recid
mydata['token'] = my_token
@ -373,4 +372,253 @@ def add_articles_avis(diction):
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de créer l'article/avis"
return False, " Impossible de créer l'article/avis"
'''
Cette fonction recherche un aricles ou avis
'''
def recherche_articles_avis(diction):
try:
'''
# Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
# Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
# Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
# field_list.
'''
field_list = ['token', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - : Le champ '" + val + "' n'existe pas, recherche annuléee")
return False, " Le champ '" + val + "' n'existe pas, recherche annulée"
'''
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
On controle que les champs obligatoires sont presents dans la liste
'''
field_list_obligatoire = ['search_text', 'token']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - La valeur '" + val + "' n'est pas presente dans liste ")
return False, " : La valeur '" + val + "' n'est pas presente dans liste "
# recuperation des paramettre
search_text = ""
user_recid = ""
token = ""
if ("search_text" in diction.keys()):
if diction['search_text']:
search_text = diction['search_text']
if ("token" in diction.keys()):
if diction['token']:
token = diction['token']
# Verification de la validité du token/mail dans le cas des user en mode connecté
if (len(str(token)) > 0):
retval = mycommon.check_token_validity("", token)
if retval is False:
mycommon.myprint(str(inspect.stack()[0][3]) + " - Le token n'est pas valide")
return False, "Le token n'est pas valide"
# Recuperation du recid de l'utilisateur
user_recid = mycommon.get_user_recid_from_token(token)
if user_recid is False:
mycommon.myprint(
str(inspect.stack()[0][3]) + " - Impossible de recuperer le token de l'utilisateur")
return False, " Impossible de desactiver l'objectif utilisateur"
mycommon.myprint(" On recehrche la phrase +'" + search_text + "' + user_recid = " + user_recid)
# Enregistrerment de la recherche
retval, message, store_recherche_Id = store_recherche_article_avis(diction, user_recid)
if (retval is False):
return retval, message
tab_training = []
tab_training = ela_index.ela_recherche_article_avis_tokens(search_text)
mycommon.myprint(" pour phrase : #" + search_text + "#, voici la liste des formations")
mycommon.myprint(tab_training)
coll_name = dbname['articles_avis']
'''
la valeur nb_result permettra de savoir si la requete a donnée un resultat.
si ce n'est pas le cas, il faudra à la fin enregistrer la requete avec un result a vide'''
nb_result = 0
insertObject = []
for val in tab_training:
for x in coll_name.find({"title_formation": str(val)},
{"_id": 0, "indexed": 0, "valide": 0, "locked": 0, }):
nb_result = nb_result + 1
my_recid = {}
my_recid['user_rec_id'] = str(user_recid)
mydict_combined = {**diction, **x, **my_recid}
mydict_combined['date_update'] = str(datetime.now())
mydict_combined['type_view'] = "summary"
if ("_id" in mydict_combined.keys()):
mydict_combined['class_id'] = mydict_combined.pop('_id')
user = x
val = x['qualite']
if (len(x['qualite']) > MAX_CARACT):
x['qualite'] = val[:MAX_CARACT] + " ..."
else:
x['qualite'] = val[:MAX_CARACT]
val = x['avis']
if (len(x['avis']) > MAX_CARACT):
x['avis'] = val[:MAX_CARACT] + " ..."
else:
x['avis'] = val[:MAX_CARACT]
insertObject.append(JSONEncoder().encode(user))
return True, insertObject
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, " Impossible de recherche un article/avis"
'''
Stockage des recherches sur les avis
'''
def store_recherche_article_avis(diction, user_recid=""):
try:
'''
# Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
# Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
# Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
# field_list.
'''
if ( len(str(user_recid)) <= 0 ):
user_recid = 'None' # by default
field_list = ['token', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text', 'certif',
'support', 'type', 'lang', 'price', 'distance', 'duration']
incom_keys = diction.keys()
for val in incom_keys:
if val not in field_list:
mycommon.myprint(str(inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas, recherche annulée")
return False, " Le champ '" + val + "' n'existe pas, recherche annulée", None
'''
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
On controle que les champs obligatoires sont presents dans la liste
'''
field_list_obligatoire = ['search_text', 'token']
for val in field_list_obligatoire:
if val not in diction:
mycommon.myprint(" : La valeur '" + val + "' n'est pas presente dans liste ")
return False, " : La valeur '" + val + "' n'est pas presente dans liste ", None
# recuperation des paramettre
mydata = {}
mydata_id = ""
my_token = ""
if ("search_text" in diction.keys()):
if diction['search_text']:
mydata['search_text'] = diction['search_text']
if ("user_mail" in diction.keys()):
if diction['user_recid']:
mydata['user_recid'] = diction['user_recid']
if ("token" in diction.keys()):
if diction['token']:
my_token = diction['token']
'''# Recuperation du recid de l'utilisateur
user_recid = mycommon.get_user_recid_from_token(my_token)
if user_recid is False:
mycommon.myprint(" Impossible d'enregistrer la recherche de utilisateur")
return False, " Impossible d'enregistrer la recherche de utilisateur"
'''
mydata['user_recid'] = user_recid
mydata['document_recherche'] = "articles_avis"
if ("source" in diction.keys()):
if diction['source']:
mydata['source'] = diction['source']
if ("name" in diction.keys()):
if diction['name']:
mydata['name'] = diction['name']
if ("id" in diction.keys()):
if diction['id']:
mydata_id = diction['id']
mydata['date_update'] = str(datetime.now())
mydata['valide'] = "1" # By default
if ("valide" in diction.keys()):
if diction['valide']:
mydata['valide'] = diction['valide']
coll_name = dbname['user_recherche']
# Si le champ "id" est renseigné, il s'agit d'une mis jour
mycommon.myprint(str(inspect.stack()[0][3]) + " on va stocker "+str(mydata)+" id = "+str(mydata_id))
if( len(str(mydata_id)) > 0 ):
ret_val = coll_name.find_one_and_update({'_id': ObjectId(str(mydata_id)), 'valide': '1'},
{"$set": mydata},
return_document=ReturnDocument.AFTER
)
if (ret_val and ret_val['_id']):
nb_doc = str(ret_val['_id'])
mycommon.myprint(str(inspect.stack()[0][3]) + " La recherche a bien été mise à jour . Le Doc Id = "+str(nb_doc))
return True, "La recherche a bien été mise à jour", ret_val['_id']
else:
return False, "Impossible de mettre à jour a la recherche", None
else:
ret_val = coll_name.insert_one(mydata)
if ret_val and ret_val.inserted_id:
nb_doc = ret_val.inserted_id
mycommon.myprint(str(inspect.stack()[0][3]) + " La recherche a été bien enregistrée. Id = '" + str(nb_doc)+"' ")
return True, "La recherche a bien été mise à jour", nb_doc
else:
mycommon.myprint(
str(inspect.stack()[0][3]) + "Impossible d'enregistrer la recherche")
return False, "Impossible d'enregistrer la recherche ", None
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'enregistrer la recherche", None

View File

@ -1,3 +1,2 @@
,index,mots,occurence,moyenne,id_formation,source_field
0,0,mot,2,0.33,AUTO_CH03,default
1,1,recherch,4,0.67,AUTO_CH03,default
0,0,formation4,0,0.0,formation4,default

1 index mots occurence moyenne id_formation source_field
2 0 0 mot formation4 2 0 0.33 0.0 AUTO_CH03 formation4 default
1 1 recherch 4 0.67 AUTO_CH03 default

View File

@ -168,7 +168,6 @@ def ela_index_class(external_code="", source_field = ""):
La fonction "ela_index_all_classes" va aller chercher chaque cours dans la BDD
et créer les mots clées qui sont ensuite enregister dans la table "elaindex"
'''
def ela_index_all_classes():
# Making a Connection with MongoClient
try:
@ -531,3 +530,153 @@ def ela_recherche_tokens_source_field(sentence, source_fied=""):
return tab_training_id
''''
Cette fonction indexe les articles et avis.
important : se ra indexé que le titre de la formation.
apres avoir été indexés la champs "indexed" passe à 1
'''
def ela_index_all_articles_avis():
# Making a Connection with MongoClient
try:
# collection
collection = db["articles_avis"]
nb_class_indexed = 0
for doc in collection.find({'indexed': '0'}):
if ("title_formation" in doc.keys()):
chaine = doc["title_formation"]
mycommon.myprint(" Debut indexation de l'article : "+chaine)
retval = ela_index_articles_avis(str(doc["title_formation"]))
print(" apres : ela_index_class retval = " + str(retval))
if (retval is False):
mycommon.myprint("IMPOSSIBLE d'indexer la formation = " + str(doc["external_code"]))
else:
nb_class_indexed = nb_class_indexed + 1
# retval = ls.ela_index_record_field(chaine, str(doc["external_code"]))
mycommon.myprint(str(nb_class_indexed) + " ont été indexes")
return True, str(nb_class_indexed) + " articles ont été indexes "
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'indexer les articles et avis ==> KO"
'''
Cette fonction indexe un article / avis
Par defaut sont pris en compte :
- le titre de la formation
'''
def ela_index_articles_avis(titre_formation="", source_field = ""):
try:
collection = db["articles_avis"]
if( len(str(source_field)) == 0):
source_field = 'default'
for doc in collection.find({"title_formation":titre_formation, "valide":"1"}):
# Indexation par defaut : champs TITRE FORMATION
if ( str(source_field) == "default" ):
chaine = doc["title_formation"]
#mycommon.myprint(" external_code = "+str(doc["external_code"])+" ==> "+str(chaine))
retval = ls.ela_index_article_avis_record_field(chaine, str(doc["title_formation"]), source_field)
'''
# Apres indexation, on met a jour la formation pour
# mettre le champ "indexe" a 1.
'''
if( retval ):
# mise à jour du champ "indexed"
myobjectif = {}
myobjectif['indexed'] = '1'
ret_val2 = collection.find_and_modify(query={"title_formation":titre_formation, "valide":"1"},
update={"$set": myobjectif}
)
if (ret_val2 and ret_val2['_id']):
mycommon.myprint("L'article indexé (champs par defaut) =" + str(ret_val2['_id']))
return True
else:
return False
return True
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - Line : " + str(exc_tb.tb_lineno))
return False
'''
Cette fonction recherche une chaine de caractère
dans la table des articles et avis.
Elle retourne le title de la formation
'''
def ela_recherche_article_avis_tokens(sentence):
tab_training_id = []
tab_tokens = ls.Ela_Tokenize(sentence)
tab_tokens2 = ls.Ela_remove_stop_words(tab_tokens)
tab_tokens3 = ls.Ela_remove_pronoun(tab_tokens2)
'''
note : 26/03 : Faire evolution la fonction ici pour
gerer les mots qui ne doivent pas etre racinisé comme le cas du mot "Responsive"
De manière plus globale, il faudrait exclure certains mot de la racinisation.
'''
print(" VERIF : " + str(tab_tokens3))
tab_corrected_word = []
for mot in tab_tokens3:
mycommon.recherche_check_word_in_fr_dict(str(mot))
val = ls.correct_fr_word(str(mot))
if (val):
tab_corrected_word.append(str(val))
print("corrected word = " + str(tab_corrected_word))
tab_tokens4 = ls.Ela_stemmize(tab_corrected_word)
print(" VERIF APRES STEMISATION : " + str(tab_tokens4))
tab_tokens4.sort()
'''
tab_tokens4 contient la liste des mots à rechercher.
En suite pour chaque mot de "tab_tokens4" on regarde dans la table "elaindex"
a quoi cela pourrait correspondre.
'''
# collection
collection = db["elaindex_article_avis"]
print(" mot recherché tab_tokens4 = " + str(tab_tokens4))
pipe2 = [{'$match': {'mots': {'$in': tab_tokens4}}},
{'$group': {
'_id': "$id_article_avis",
'count_class': {'$sum': 1},
'sum_occurence': {'$sum': '$occurence'}
}
},
{'$sort': {'count_class': -1, 'sum_occurence': -1}}
]
for result in collection.aggregate(pipe2):
tab_training_id.append(str(result["_id"]))
# print(result)
print("resultat tab_training_id = " + str(tab_training_id))
return tab_training_id

View File

@ -1,3 +1,2 @@
mots occurence moyenne id_formation source_field
0 mot 2 0.33 AUTO_CH03 default
1 recherch 4 0.67 AUTO_CH03 default
mots occurence moyenne id_formation source_field
0 formation4 0 0.0 formation4 default

27
main.py
View File

@ -878,6 +878,33 @@ def add_articles_avis():
return jsonify(status=status, message=retval)
'''
Cette API indexe les articles et avis postés
'''
@app.route('/myclass/api/ela_index_all_articles_avis/', methods=['POST','GET'])
@crossdomain(origin='*')
def ela_index_all_articles_avis():
# On recupere le corps (payload) de la requete
payload = request.form.to_dict()
print(" ### payload = ",payload)
status, retval = ela_index_class.ela_index_all_articles_avis()
return jsonify(status=status, message=retval)
'''
Cette API recherche un articles ou un avis en se basant sur le
titre de la formation'''
@app.route('/myclass/api/recherche_articles_avis/', methods=['GET','POST'])
@crossdomain(origin='*')
def recherche_articles_avis():
# On recupere le corps (payload) de la requete
payload = request.form.to_dict()
print(" ### payload = ", payload)
status, result = aa.recherche_articles_avis(payload)
return jsonify(status=status, message=result)
if __name__ == '__main__':
print(" debut api")

View File

@ -503,10 +503,7 @@ def recherche_text_simple(diction):
coll_name = dbname['myclass']
print(" Dans la recherch, les critère = "+str(certif_crit)+" la langue = "+str(lang_crit)+
" price = "+str(price_crit)+" Duration = "+str(duration_crit))
#ici ajouter tous les critère comme ci-dessous avec le support et le certif
'''
la valeur nb_result permettra de savoir si la requete a donnée un resultat.
si ce n'est pas le cas, il faudra à la fin enregistrer la requete avec un result a vide'''
@ -529,7 +526,6 @@ def recherche_text_simple(diction):
if ("_id" in mydict_combined.keys()):
mydict_combined['class_id'] = mydict_combined.pop('_id')
#mycommon.myprint("COMBINED = " + str(mydict_combined))
'''
Statistique : Insertion du recherche - resultat '''
@ -662,6 +658,7 @@ def store_recherche(diction, user_recid=""):
return False, " Impossible d'enregistrer la recherche de utilisateur"
'''
mydata['user_recid'] = user_recid
mydata['document_recherche'] = "formation"
if ("type" in diction.keys()):
if diction['type']: