Ela_Back/ela_index_bdd_classes.py

1190 lines
49 KiB
Python

from pymongo import MongoClient
import Ela_Spacy as ls
import prj_common as mycommon
from pymongo import ReturnDocument
import inspect
import sys, os
from operator import itemgetter, attrgetter
import GlobalVariable as MYSY_GV
from datetime import datetime
'''
Cette fonction indexe une formation
Par defaut sont pris en compte :
- le titre et
- la description
'''
def ela_index_class(external_code="", source_field = "", partner_owner_recid = ""):
try:
collection = MYSY_GV.dbname["myclass"]
if( len(str(source_field)) == 0):
source_field = 'default'
for doc in collection.find({"external_code":external_code}):
# Indexation par defaut : champs TITRE + DESCRIPTION
if ( str(source_field) == "default" ):
chaine = doc["title"]+" - "+doc["description"]
chaine = mycommon.cleanhtml(chaine)
#mycommon.myprint(" external_code = "+str(doc["external_code"])+" ==> "+str(chaine))
retval = ls.ela_index_record_field(chaine, str(doc["external_code"]), source_field, partner_owner_recid)
'''
# 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_one_and_update({"external_code":external_code},
{"$set": myobjectif},
return_document=ReturnDocument.AFTER
)
if (ret_val2 and ret_val2['_id']):
mycommon.myprint("La formation indexée (champs par defaut) =" + str(ret_val2['_id']))
return True
else:
return False
# Indexation du champ : title
elif ( str(source_field) == "title" ):
chaine = doc["title"]
chaine = mycommon.cleanhtml(chaine)
# mycommon.myprint(" external_code = "+str(doc["external_code"])+" ==> "+str(chaine))
retval = ls.ela_index_record_field(chaine, str(doc["external_code"]), source_field, partner_owner_recid)
'''
# 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_title'] = '1'
ret_val2 = collection.find_one_and_update({"external_code": external_code},
{"$set": myobjectif},
return_document=ReturnDocument.AFTER
)
if (ret_val2 and ret_val2['_id']):
mycommon.myprint("La formation indexée (champ title) =" + str(ret_val2['_id']))
return True
else:
return False
# Indexation du champ : description
elif ( str(source_field) == "description" ):
chaine = doc["description"]
chaine = mycommon.cleanhtml(chaine)
# mycommon.myprint(" external_code = "+str(doc["external_code"])+" ==> "+str(chaine))
retval = ls.ela_index_record_field(chaine, str(doc["external_code"]), source_field, partner_owner_recid)
'''
# 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_desc'] = '1'
ret_val2 = collection.find_one_and_update({"external_code": external_code},
{"$set": myobjectif},
return_document=ReturnDocument.AFTER
)
if (ret_val2 and ret_val2['_id']):
mycommon.myprint("La formation indexée (champ description) =" + str(ret_val2['_id']))
return True
else:
return False
# Indexation du champ : Objectif
elif ( str(source_field) == "objectif" ):
chaine = doc["objectif"]
chaine = mycommon.cleanhtml(chaine)
# mycommon.myprint(" external_code = "+str(doc["external_code"])+" ==> "+str(chaine))
retval = ls.ela_index_record_field(chaine, str(doc["external_code"]), source_field, partner_owner_recid)
'''
# 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_obj'] = '1'
ret_val2 = collection.find_one_and_update({"external_code": external_code},
{"$set": myobjectif},
return_document=ReturnDocument.AFTER
)
if (ret_val2 and ret_val2['_id']):
mycommon.myprint("La formation indexée (champs objectif) =" + str(ret_val2['_id']))
return True
else:
return False
# Indexation du champ : mot_cle
elif (str(source_field) == "keyword"):
chaine = doc["mots_cle"]
chaine = mycommon.cleanhtml(chaine)
# mycommon.myprint(" external_code = "+str(doc["external_code"])+" ==> "+str(chaine))
retval = ls.ela_index_record_field(chaine, str(doc["external_code"]), source_field, partner_owner_recid)
'''
# 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_keyword'] = '1'
ret_val2 = collection.find_one_and_update({"external_code": external_code},
{"$set": myobjectif},
return_document=ReturnDocument.AFTER
)
if (ret_val2 and ret_val2['_id']):
mycommon.myprint("La formation indexée (champs objectif) =" + str(ret_val2['_id']))
return True
else:
return False
# Indexation du champ : video_text , donc la transcription d'une video
elif (str(source_field) == "video_text"):
chaine = doc["video_text"]
chaine = mycommon.cleanhtml(chaine)
# mycommon.myprint(" external_code = "+str(doc["external_code"])+" ==> "+str(chaine))
retval = ls.ela_index_record_field(chaine, str(doc["external_code"]), source_field, partner_owner_recid)
'''
# 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_video_text'] = '1'
ret_val2 = collection.find_one_and_update({"external_code": external_code},
{"$set": myobjectif},
return_document=ReturnDocument.AFTER
)
if (ret_val2 and ret_val2['_id']):
mycommon.myprint("La formation indexée (champs video_text) =" + 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False
"""
Indexation des mots clés.
Ceci etant particulier, il n'ya pas de gestion d'occurence.
/!\ : A faire.
Pour chaque mot clé,
1 - Ajouter le mot dans la collection "word_not_stem" pour eviter les effets de traduction
2 - Ajouter les mot dans la collection "elaindex" avec une occurrence par defaut de 1000, source_field = 'keyword', moyanne = "1"
"""
def ela_index_class_key_word(external_code="", source_field = "", partner_owner_recid=""):
try:
if( str(external_code).strip() == "" or str(source_field).strip() == "" ):
mycommon.myprint( str(inspect.stack()[0][3]) + " Toutes les information ne sont pas fournies (1) ")
return False,
if( str(source_field).strip() != "keyword"):
mycommon.myprint(str(inspect.stack()[0][3]) + " Il ne s'agit pas d'une indexation de mot clés")
return False
# Recuperation de la liste des mots clée
#print(" ### external_code = ", external_code)
local_class = MYSY_GV.dbname['myclass'].find_one({"external_code": external_code, 'valide':'1', 'locked':'0'})
#print(" ## local_class = ", local_class)
if( local_class is None ):
mycommon.myprint(str(inspect.stack()[0][3]) + " Aucune formation à indexer (1) pour "+str(external_code))
return False
if ("mots_cle" not in local_class.keys()):
mycommon.myprint(str(inspect.stack()[0][3]) + " Aucune formation à indexer (2) pour "+str(external_code))
return False
"""
On supprimer les anciens mots indexé
"""
MYSY_GV.dbname['elaindex'].delete_many({ 'source_field': 'keyword',
'id_formation': str(local_class['external_code']),
'partner_owner_recid':str(partner_owner_recid)})
MYSY_GV.dbname['word_not_stem'].delete_many({'id_formation': str(local_class['external_code'])})
now = str(datetime.now())
"""
Ajouter les mots dans la collection word_not_stem
"""
cpt = 0
list_mots_cle = mycommon.cleanhtml(local_class['mots_cle'])
list_keyword = str(list_mots_cle).replace(",",";").split(";")
for val in list_keyword :
if(len(str(val).strip()) > 0 ):
cpt = cpt + 1
# Ajout dant not_stem
MYSY_GV.dbname['word_not_stem'].insert_one({'mot':str(val).strip().lower(), 'date_update':str(now), 'id_formation':str(local_class['external_code'])})
# Ajouter les mot dans la collection "elaindex" avec une occurrence par defaut de 1000, source_field = 'keyword', moyanne = "1"
MYSY_GV.dbname['elaindex'].insert_one({'mots': str(val).strip().lower(), 'occurence': 1000,
'source_field':'keyword', 'moyenne':"1",
'id_formation':str(local_class['external_code']),
'partner_owner_recid':str(partner_owner_recid)})
mycommon.myprint(str(inspect.stack()[0][3]) + " " +str(cpt)+" mot(s) clé(s) ont été indexés pour la formation "+str(local_class['external_code']))
return True
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False
'''
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(partner_owner_recid):
# Making a Connection with MongoClient
try:
# collection
collection = MYSY_GV.dbname["myclass"]
'''
ATTENTION ATTENTION
/!\ : avant l'indexation, on vide la table des indexes.
cette logique est tres gourmande.
ce quil faudrait faire :
- si une formation est indexée, mettre un fag pour dire : indexé => OK
- si on met à jour une formation ==> Mettre le flag à KO
- si on ajoute une formation, mettre le flag à KO
Pour mutualiser le process entre l'indexation des tous les champs ou l'indexation de uniquement de certain champs
ex : indexation du champ 'title' ou du champ 'objectif', je vais introduitre la notion de 'source_fied'
pour l'indexation title, 'source_fied' = 'title'
pour l'indexation objectif, 'source_fied' = 'objectif'
apres pour l'indexation, il ne faudra indexer que les formations dont le flag est KO.
aussi, avant d'indexer une formation, supprimer tous les index de la dite formation pour remplacer tous les anciens et eviter un doublon
'''
nb_class_indexed = 0
for doc in collection.find({'indexed':'0'}):
if ("title" in doc.keys() and "description" in doc.keys() ):
chaine = doc["title"]+" - "+doc["description"]
mycommon.myprint(" external_code = "+str(doc["external_code"])+" ==> "+str(chaine))
retval = ela_index_class(str(doc["external_code"]), partner_owner_recid)
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)+" 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'indexer la BDD des formations ==> KO"
'''
Cette fonction va indexer les mots clés ajoutés à une formation.
Par defaut, seul 3 mots clés sont acceptés par formation.
les mots clés sont separés par des ";".
ex : mot1;mot2;mot3
'''
def ela_index_all_classes_keywords(partner_owner_recid):
try:
collection = MYSY_GV.dbname["myclass"]
nb_class_indexed = 0
for doc in collection.find({'indexed_keyword': '0'}):
if ("mots_cle" in doc.keys()):
chaine = doc["mots_cle"]
mycommon.myprint(" external_code = " + str(doc["external_code"]) + " ==> " + str(chaine))
retval = ela_index_class(str(doc["external_code"]), "keyword", partner_owner_recid)
print(" apres : ela_index_all_classes_title retval = " + str(retval))
if (retval is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + "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) + " 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'indexer la BDD des formations ==> KO"
"""
Cette fonction va indexer les mots clés d'une formation donnée ou toutes les formations d'un partenaire.
Pour ce faire elle prend en argument :
- internal_url
- partenaire_recid
/!\ Important : La fonction peut reindexer les formations si l'argument
reindexe = 1
"""
def ela_index_given_classes_keywords(diction) :
# Making a Connection with MongoClient
try:
# Dictionnaire des champs utilisables
field_list = ['internal_url', 'partner_owner_recid', 'reindex_all']
incom_keys = diction.keys()
'''
# 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.
'''
for val in incom_keys:
if str(val).lower() not in str(field_list).lower():
mycommon.myprint(str(inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas, MAJ annulée")
return False, " Impossible de se connecter, merci de contacter le support technique"
check = False
internal_url = ""
if ("internal_url" in diction.keys()):
if diction['internal_url']:
check = True
internal_url = diction['internal_url']
partner_owner_recid = ""
if ("partner_owner_recid" in diction.keys()):
if diction['partner_owner_recid']:
check = True
partner_owner_recid = diction['partner_owner_recid']
reindex_all = ""
if ("reindex_all" in diction.keys()):
if diction['reindex_all']:
check = True
reindex_all = diction['reindex_all']
if( check is False ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Aucune formation à indexer")
return True, " Aucune formation à indexer"
collection = MYSY_GV.dbname["myclass"]
nb_class_indexed = 0
myquery = {'valide':'1'}
if( internal_url and len(str(internal_url)) > 0 ):
myquery['internal_url'] = internal_url
if (partner_owner_recid and len(str(partner_owner_recid)) > 0):
myquery['partner_owner_recid'] = partner_owner_recid
if (reindex_all and len(str(reindex_all)) > 0):
if(reindex_all != "1" ):
myquery['indexed_keyword'] = "0"
print(" QUERY INDEX keyword ="+str(myquery))
for doc in collection.find(myquery):
if ("mots_cle" in doc.keys()):
chaine = doc["mots_cle"]
mycommon.myprint(" external_code = " + str(doc["external_code"]) + " ==> " + str(chaine))
retval = ela_index_class(str(doc["external_code"]), "keyword", partner_owner_recid)
print(" apres : ela_index_given_classes_keywords retval = " + str(retval))
if (retval is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + "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 ==> keyword")
return True, str(nb_class_indexed) + " ont été indexes ==> keyword"
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'indexer la BDD des formations ==> KO"
'''
La fonction "ela_index_all_classes_title" va aller chercher chaque cours dans la BDD
et créer les mots clées des title qui sont ensuite enregister dans la table "elaindex"
'''
def ela_index_all_classes_title(partner_owner_recid):
# Making a Connection with MongoClient
try:
collection = MYSY_GV.dbname["myclass"]
'''
ATTENTION ATTENTION
/!\ : avant l'indexation, on vide la table des indexes.
cette logique est tres gourmande.
ce quil faudrait faire :
- si une formation est indexée, mettre un fag pour dire : indexé => OK
- si on met à jour une formation ==> Mettre le flag à KO
- si on ajoute une formation, mettre le flag à KO
ex : indexation du champ 'title' ou du champ 'objectif', je vais introduitre la notion de 'source_fied'
pour l'indexation title, 'source_fied' = 'title'
pour l'indexation objectif, 'source_fied' = 'objectif'
apres pour l'indexation, il ne faudra indexer que les formations dont le flag est KO.
aussi, avant d'indexer une formation, supprimer tous les index de la dite formation pour remplacer tous les anciens et eviter un doublon
'''
nb_class_indexed = 0
for doc in collection.find({'indexed_title': '0'}):
if ("title" in doc.keys()):
chaine = doc["title"]
mycommon.myprint(" external_code = " + str(doc["external_code"]) + " ==> " + str(chaine))
retval = ela_index_class(str(doc["external_code"]), "title", partner_owner_recid)
print(" apres : ela_index_all_classes_title retval = " + str(retval))
if (retval is False):
mycommon.myprint(str(inspect.stack()[0][3]) + "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) + " 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) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'indexer la BDD des formations ==> KO"
"""
Cette fonction va indexer une formation donnée ou toutes les formations d'un partenaire.
Pour ce faire elle prend en argument :
- internal_url
- partenaire_recid
/!\ Important : La fonction peut reindexer les formations si l'argument
reindexe = 1
"""
def ela_index_given_classes_title(diction) :
# Making a Connection with MongoClient
try:
# Dictionnaire des champs utilisables
field_list = ['internal_url', 'partner_owner_recid', 'reindex_all']
incom_keys = diction.keys()
'''
# 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.
'''
for val in incom_keys:
if str(val).lower() not in str(field_list).lower():
mycommon.myprint(str(inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas, MAJ annulée")
return False, " Impossible de se connecter, merci de contacter le support technique"
check = False
internal_url = ""
if ("internal_url" in diction.keys()):
if diction['internal_url']:
check = True
internal_url = diction['internal_url']
partner_owner_recid = ""
if ("partner_owner_recid" in diction.keys()):
if diction['partner_owner_recid']:
check = True
partner_owner_recid = diction['partner_owner_recid']
reindex_all = ""
if ("reindex_all" in diction.keys()):
if diction['reindex_all']:
check = True
reindex_all = diction['reindex_all']
if( check is False ):
mycommon.myprint(str(inspect.stack()[0][3]) + " - Aucune formation à indexer")
return True, " Aucune formation à indexer"
collection = MYSY_GV.dbname["myclass"]
nb_class_indexed = 0
myquery = {'valide':'1'}
if( internal_url and len(str(internal_url)) > 0 ):
myquery['internal_url'] = internal_url
if (partner_owner_recid and len(str(partner_owner_recid)) > 0):
myquery['partner_owner_recid'] = partner_owner_recid
if (reindex_all and len(str(reindex_all)) > 0):
if(reindex_all != "1" ):
myquery['indexed_title'] = "0"
print(" QUERY INDEX TITLE ="+str(myquery))
for doc in collection.find(myquery):
if ("title" in doc.keys()):
chaine = doc["title"]
mycommon.myprint(" external_code = " + str(doc["external_code"]) + " ==> " + str(chaine))
retval = ela_index_class(str(doc["external_code"]), "title", partner_owner_recid)
print(" apres : ela_index_given_classes_title retval = " + str(retval))
if (retval is False):
mycommon.myprint(
str(inspect.stack()[0][3]) + "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 => title")
return True, str(nb_class_indexed) + " ont été indexes => title "
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'indexer la BDD des formations ==> KO"
'''
La fonction "ela_index_all_classes_desc" va aller chercher chaque cours dans la BDD
et créer les mots clées des "description" qui sont ensuite enregister dans la table "elaindex"
'''
def ela_index_all_classes_desc(partner_owner_recid):
# Making a Connection with MongoClient
try:
client = MongoClient("mongodb://localhost:27017/")
# database
db = client["cherifdb"]
# collection
collection = MYSY_GV.dbname["myclass"]
'''
ATTENTION ATTENTION
/!\ : avant l'indexation, on vide la table des indexes.
cette logique est tres gourmande.
ce quil faudrait faire :
- si une formation est indexée, mettre un fag pour dire : indexé => OK
- si on met à jour une formation ==> Mettre le flag à KO
- si on ajoute une formation, mettre le flag à KO
ex : indexation du champ 'title' ou du champ 'objectif', je vais introduitre la notion de 'source_fied'
pour l'indexation title, 'source_fied' = 'title'
pour l'indexation objectif, 'source_fied' = 'objectif'
apres pour l'indexation, il ne faudra indexer que les formations dont le flag est KO.
aussi, avant d'indexer une formation, supprimer tous les index de la dite formation pour remplacer tous les anciens et eviter un doublon
'''
nb_class_indexed = 0
for doc in collection.find({'indexed_desc': '0'}):
if ("description" in doc.keys()):
chaine = doc["description"]
mycommon.myprint(" external_code = " + str(doc["external_code"]) + " ==> " + str(chaine))
retval = ela_index_class(str(doc["external_code"]), "description", partner_owner_recid)
print(" apres : ela_index_all_classes_title 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 - champ description")
return True, str(nb_class_indexed) + " ont été indexes - champ description "
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'indexer la BDD des formations ==> KO"
'''
La fonction "ela_index_all_classes_desc" va aller chercher chaque cours dans la BDD
et créer les mots clées des "objectif" qui sont ensuite enregister dans la table "elaindex"
'''
def ela_index_all_classes_obj(partner_owner_recid):
# Making a Connection with MongoClient
try:
# collection
collection = MYSY_GV.dbname["myclass"]
'''
ATTENTION ATTENTION
/!\ : avant l'indexation, on vide la table des indexes.
cette logique est tres gourmande.
ce quil faudrait faire :
- si une formation est indexée, mettre un fag pour dire : indexé => OK
- si on met à jour une formation ==> Mettre le flag à KO
- si on ajoute une formation, mettre le flag à KO
ex : indexation du champ 'title' ou du champ 'objectif', je vais introduitre la notion de 'source_fied'
pour l'indexation title, 'source_fied' = 'title'
pour l'indexation objectif, 'source_fied' = 'objectif'
apres pour l'indexation, il ne faudra indexer que les formations dont le flag est KO.
aussi, avant d'indexer une formation, supprimer tous les index de la dite formation pour remplacer tous les anciens et eviter un doublon
'''
nb_class_indexed = 0
for doc in collection.find({'indexed_obj': '0'}):
if ("objectif" in doc.keys()):
chaine = doc["objectif"]
mycommon.myprint(" external_code = " + str(doc["external_code"]) + " ==> " + str(chaine))
retval = ela_index_class(str(doc["external_code"]), "objectif", partner_owner_recid)
print(" apres : ela_index_all_classes_title 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 - champ objectif")
return True, str(nb_class_indexed) + " ont été indexes - champ objectif "
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'indexer la BDD des formations ==> KO"
'''
Cette fonction lire la transcription d'une video et
l'indexer'''
def ela_index_all_classes_video_text(partner_owner_recid):
# Making a Connection with MongoClient
try:
# collection
collection = MYSY_GV.dbname["myclass"]
'''
ATTENTION ATTENTION
/!\ : avant l'indexation, on vide la table des indexes.
cette logique est tres gourmande.
ce quil faudrait faire :
- si une formation est indexée, mettre un fag pour dire : indexé => OK
- si on met à jour une formation ==> Mettre le flag à KO
- si on ajoute une formation, mettre le flag à KO
ex : indexation du champ 'title' ou du champ 'objectif', je vais introduitre la notion de 'source_fied'
pour l'indexation title, 'source_fied' = 'title'
pour l'indexation objectif, 'source_fied' = 'objectif'
apres pour l'indexation, il ne faudra indexer que les formations dont le flag est KO.
aussi, avant d'indexer une formation, supprimer tous les index de la dite formation pour remplacer tous les anciens et eviter un doublon
'''
nb_class_indexed = 0
for doc in collection.find({'indexed_video_text': '0'}):
if ("video_text" in doc.keys()):
chaine = doc["video_text"]
#mycommon.myprint(" video_texte = " + str(doc["external_code"]) + " ==> " + str(chaine))
retval = ela_index_class(str(doc["external_code"]), "video_text", partner_owner_recid)
#print(" apres : ela_index_all_classes_video_texte 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 - champ video_text")
return True, str(nb_class_indexed) + " ont été indexes - champ video_text "
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Impossible d'indexer video_text la BDD des formations ==> KO"
'''
Cette fonction recherche une chaine de caractère
dans la base de données.
cette recherche concerne les 'tuple' avec "source_field":"default" ==> l'indexation par defaut.
Elle retourne l'id_externe de la formation
'''
def ela_recherche_tokens(sentence):
try:
tab_training_id = []
status, tab_tokens = ls.Ela_Tokenize(sentence)
if( status is False):
return False
status, tab_tokens2 = ls.Ela_remove_stop_words(tab_tokens)
if (status is False):
return False
status, tab_tokens3 = ls.Ela_remove_pronoun(tab_tokens2)
if (status is False):
return False
'''
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 ICI : "+str(tab_tokens3))
status, tab_tokens4 = ls.Ela_stemmize_search(tab_tokens3)
if( status is False):
return False
print(" VERIF APRES STEMISATION AA: " + str(tab_tokens4))
"""
24/05/2025 pr test on va annuler la Ela_stemmize_search
"""
tab_tokens4 = tab_tokens3
"""
end test : ca l'air de fonctionner à retester bien
"""
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 = MYSY_GV.dbname["elaindex"]
print(" mot recherché tab_tokens4 (initialement) = "+str(tab_tokens4))
status, new_tab_tokens4 = mysy_recherche_levenshtein(tab_tokens4)
if( status is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " Recherche : mysy_recherche_levenshtein return FALSE ")
return []
print(" ### les nouveaux mots recherchés new_tab_tokens4 = " + str(new_tab_tokens4))
pipe2 = [{ '$match': { 'mots': { '$in': new_tab_tokens4 } } },
{ '$group': {
'_id': "$id_formation",
'count_class': {'$sum': 1},
'sum_occurence': {'$sum': '$occurence'}
}
},
{'$sort': { 'sum_occurence': -1, 'count_class': -1,}},
{'$limit': MYSY_GV.QUERY_LIMIT_ROW}
]
print(" #### CRITERE DE CHERCHE pipe2 = "+str(pipe2))
# ici limite à 4
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
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False
'''
Cette fonction essayer de faire une recherche de leveinstein
elle prend une liste mot :
pr chaque mot,
1 - elle prends les 3 premier caractère
2 - recherche ceux qui correspondent
3 - pour chaque mot trouvé, faire un distance de levein et voir
puis elle retourne la liste des mots trouvé dans la table elaindex
Regles fonctionnelles :
Si 0 < len(mot) <= 3 ==> Recherche strict à faire
Si 3 < len(mot) <= 5 ==> Recherche avec une distance de 1
Si 5 < len(mot) <= 10 ==> Recherche avec une distance de 2
Si 10 < len(mot) ==> Recherche avec une distance de 3
'''
def mysy_recherche_levenshtein(tab_mot):
try:
coll_name = MYSY_GV.dbname['elaindex']
training_mots = []
print("mysy_recherche_levenshtein debut "+str(tab_mot))
for mot in tab_mot:
'''
Si le mot appartient à la collection "word_not_stem", alors il faut faire un recherche strict
pas de recherche elastique à faire.
'''
'''print("### + #### '" + str(mot) + "' mycommon.Word_Not_Stemmize(str(mot) = '" +
str(mycommon.Word_Not_Stemmize(str(mot))))
'''
if (mycommon.Word_Not_Stemmize(str(mot)) is True):
# "recherche strict"
if (str(mot) not in training_mots):
#print(" Le mot " + str(mot) + " est dans la table 'word_not_stem', donc pas de recherche elastique")
training_mots.append(str(mot))
else:
if( len( mot ) > 3):
"""
/!\ Update du 29/09/22 :
J'ai rendu le mysy_recherche_levenshtein un peu souple en
en disant que si taille du mot > 5 alors j'accepte une distance de 2 à condition que 4 première lettre soient identiques
"""
mot_first_caract = mot[0:4]
#print(" Traitement de " + str(mot) + " = 3 first => " + str(mot_first_caract))
v = {'$regex': "^" + mot_first_caract}
#print("v = " + str(v))
for x in coll_name.find({'mots': v}):
cmp_levenshtein = int(mycommon.levenshtein(mot, str(x['mots'])))
#print(" check ### ="+str(x['mots']))
if( len(mot) <= 5 and cmp_levenshtein <= 0):
if( str(x['mots']) not in training_mots):
training_mots.append( str(x['mots']) )
elif( len(mot) <= 10 and cmp_levenshtein <= 1):
if( str(x['mots']) not in training_mots):
training_mots.append( str(x['mots']) )
elif ( cmp_levenshtein <= 1):
if (str(x['mots']) not in training_mots):
training_mots.append(str(x['mots']))
'''elif (cmp_levenshtein > 3):
print(" KOOFF cmp_levenshtein : " + mot + " CMP " + str(x['mots']) + " = " + str(cmp_levenshtein) +
" ==> id_formation" + str(x['id_formation']) + " ==> occurrence = " + str(x['occurence']))
'''
print("mysy_recherche_levenshtein FINN " + str(training_mots))
return True, training_mots
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, None
'''
Cette fonction recherche une chaine de caractère
dans la base, mais sur indexation bien precise.
par exemple, pour gerer les recherche par tips :'title':'sentense', le système cherchera a identifier
les mots de "sentense" dans les indexation des titre.
Cela revient a chercher "sentence" dans la table "ela_index", where "source_field" = "title"
Elle retourne l'id_externe de la formation
'''
def ela_recherche_tokens_source_field(sentence, source_fied=""):
try:
if( len(str(source_fied)) == 0):
mycommon.myprint(str(inspect.stack()[0][3])+" - source_fied est vide")
return False
# Verification que source_field correspond a la bonne colonne
field_list = ['default', 'title', 'description','objectif',]
if source_fied not in field_list:
mycommon.myprint(str(inspect.stack()[0][3])+" - Le champ '" + source_fied + "' n'existe pas, requete annulée")
return False
print(" ici: sentence = "+sentence+", -- source_fied ="+source_fied)
tab_training_id = []
status, tab_tokens = ls.Ela_Tokenize(sentence)
if( status is False):
return False
status, tab_tokens2 = ls.Ela_remove_stop_words(tab_tokens)
if (status is False):
return False
status, tab_tokens3 = ls.Ela_remove_pronoun(tab_tokens2)
if (status is False):
return False
'''
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))
status, tab_tokens4 = ls.Ela_stemmize_search(tab_tokens3)
if (status is False):
return False
#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 = MYSY_GV.dbname["elaindex"]
print(" mot recherchéee tab_tokens4 (initialement) = " + str(tab_tokens4))
status, new_tab_tokens4 = mysy_recherche_levenshtein(tab_tokens4)
if (status is False):
mycommon.myprint(str(inspect.stack()[0][3]) + " Recherche : mysy_recherche_levenshtein return FALSE ")
return []
#print(" ### les nouveaux mots recherchés new_tab_tokens4 = " + str(new_tab_tokens4))
for token in new_tab_tokens4:
#print(" #### Token rechercher dans l'index est : '"+str(token)+"' et le source_field = '"+str(source_fied)+"' ")
for doc in collection.find({"mots":token, "source_field":source_fied}):
#print(" Trouvé dans le cours N° "+str(doc["id_formation"]))
if str(doc["id_formation"]) not in tab_training_id :
tab_training_id.append(str(doc["id_formation"]))
#print(" Pour la phrase "+str(sentence)+", voici les formations correspondantes")
#print(tab_training_id)
return tab_training_id
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
return False, "Traitement impossible "
''''
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(partner_owner_recid):
# Making a Connection with MongoClient
try:
# collection
collection = MYSY_GV.dbname["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), partner_owner_recid)
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) + " - ERRORRRR AT 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 = MYSY_GV.dbname["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_one_and_update({"title_formation":titre_formation, "valide":"1"},
{"$set": myobjectif},
return_document=ReturnDocument.AFTER
)
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) + " - ERRORRRR AT 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))
status, tab_tokens4 = ls.Ela_stemmize(tab_corrected_word)
if( status is False):
return False
print(" VERIF APRES STEMISATION BB: " + 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 = MYSY_GV.dbname["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}},
{'$limit': MYSY_GV.QUERY_LIMIT_ROW}
]
# ici limit on rows
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