Un moteur de recherche très naïf implémenté avec Django-2.1.3, python3.6.
Je suis nouveau sur Django et je ne maîtrise pas très bien l'écriture, donc ce code est uniquement à titre de référence.
première page
Pagination
Nous devons sauvegarder un index inversé, ainsi que l'heure d'envoi, l'expéditeur, le sujet, le lien du sujet, etc. correspondant à un sujet. J'ai donc conçu la structure de base de données suivante.
isIndexed
).Il convient de noter que l'ajout d'une paire clé-valeur ne peut pas utiliser le code suivant
word . index [ doc . id ] = num
word . save ()
devrait
dic = word . index
dic [ doc . id ] = num
word . index = dic
word . save ()
Ci-dessous se trouve le code du modèle dans Django
from django . db import models
class Doc ( models . Model ):
sendTime = models . DateField () # 2018-12-12 , differ from DateTimeField which can be datetime or date
sender = models . CharField ( max_length = 20 )
messageType = models . CharField ( max_length = 20 ) # Journal, conf, et al
subject = models . CharField ( max_length = 100 )
begin = models . DateField ()
deadline = models . DateField ()
subjectUrl = models . CharField ( max_length = 100 )
webpageUrl = models . CharField ( max_length = 100 )
desc = models . CharField ( max_length = 250 , default = '' )
loc = models . CharField ( max_length = 40 , default = '' )
keywords = models . CharField ( max_length = 200 , default = '' )
def __str__ ( self ):
return self . subjectUrl
import json
class Wordindex ( models . Model ):
word = models . CharField ( max_length = 45 )
# model to store a list, another way is to create a custom field
_index = models . TextField ( null = True )
@ property
def index ( self ):
return json . loads ( self . _index )
@ index . setter
def index ( self , li ):
self . _index = json . dumps ( li )
def __str__ ( self ):
return self . word
class File ( models . Model ):
doc = models . OneToOneField ( Doc , on_delete = models . CASCADE )
content = models . TextField ( null = True )
isIndexed = models . BooleanField ( default = False )
def __str__ ( self ):
return 'file: {} -> doc: {}' . format ( self . id , self . doc . id )
La première est la page d'accueil. Sa structure est la suivante.
< TBODY >
< TR VALIGN = TOP >
< TD > 03-Jan-2019 </ TD >
< TD > conf. ann. </ TD >
< TD > marta cimitile </ TD >
< TD > < A HREF =" http://www.cs.wisc.edu/dbworld/messages/2019-01/1546520301.html " rel =" nofollow " > Call forFUZZ IEEE Special Session </ A > </ TD >
< TD > 13-Jan-2019 </ TD >
< TD > < A rel =" nofollow " HREF =" http://sites.ieee.org/fuzzieee-2019/special-sessions/ " > web page </ A > </ TD >
</ TR > </ TBODY >
Il existe des régularités et peuvent être extraites directement lors de l'implémentation, j'ai utilisé le package BeautifulSoup de python pour extraire.
Pendant l'utilisation, la clé est de passer l'analyseur. J'ai essayé le HTML, mais il y a eu un problème avec lxml. Enfin, j'ai utilisé html5lib.
Ensuite, il y a la quatrième colonne (c'est-à-dire la quatrième balise td) dans le tableau ci-dessus, où la balise <a>
est le lien vers la page Web où se trouve le sujet. Elle doit également être extraite.
Étant donné que le temps et le lieu ont des modèles généraux, les modèles communs peuvent être répertoriés et mis en correspondance à l'aide d'expressions régulières.
En utilisant l'algorithme textrank, j'ai d'abord implémenté moi-même un algorithme textrank très basique, mais l'effet était très médiocre. Plus tard, j'ai utilisé la version officielle de text-rank.
Cette partie est basée sur le principe de l'index inversé, segmentant le texte de la page Web en mots, supprimant les signes de ponctuation, etc., puis utilisant le modèle de base de données présenté ci-dessus pour stocker l'index inversé.
Tout d'abord, sous le titre se trouve une rangée d'options, qui peuvent être triées en fonction de ces champs. Ensuite, il y a un bouton de mise à jour sur la ligne suivante et un formulaire de soumission de recherche.
Le contenu suivant représente les résultats de la recherche organisés à l’aide div
.
Chaque résultat contient un titre, des mots-clés, une heure, un lieu et un résumé.
Ici, j'ai moi-même implémenté l'algorithme tf-idf
pour trier les résultats. Le code est le suivant.
def tfidf ( words ):
if not words : return docs
ct = process ( words )
weight = {}
tf = {}
for term in ct :
try :
tf [ term ] = Wordindex . objects . get ( word = term ). index
except Exception as e :
print ( e )
tf [ term ] = {}
continue
for docid in tf [ term ]:
if docid not in weight :
weight [ docid ] = 0
N = len ( weight )
for term in ct :
dic = tf [ term ]
for docid , freq in dic . items ():
w = ( 1 + log10 ( freq )) * ( log10 ( N / len ( dic ))) * ct [ term ]
if term in stopWords :
w *= 0.3
weight [ docid ] += w
ids = sorted ( weight , key = lambda k : weight [ k ], reverse = True )
if len ( ids ) < 8 : pass #???
return [ Doc . objects . get ( id = int ( i )). __dict__ for i in ids ]