Προγραμματισμός

Η μηχανή αναζήτησης Lucene: Ισχυρή, ευέλικτη και δωρεάν

Μην αφήσετε τον χαμηλό αριθμό έκδοσης - 0,04 από τον Αύγουστο του 2000 - να σας ξεγελάσει. Η μηχανή αναζήτησης Lucene είναι μια ισχυρή, ισχυρή και ευέλικτη εργαλειοθήκη αναζήτησης, έτοιμη να αντιμετωπίσει πολλά κοινά προβλήματα αναζήτησης. Και δεδομένου ότι είναι πλέον διαθέσιμο με την πιο ευέλικτη άδεια ανοιχτού κώδικα LGPL, η τιμή (δωρεάν!) Είναι επίσης σωστή.

Ο Doug Cutting, ένας έμπειρος προγραμματιστής εργαλείων αναζήτησης κειμένου και ανάκτησης, δημιούργησε τη Lucene. Η Cutting είναι ο κύριος συγγραφέας της μηχανής αναζήτησης V-Twin (μέρος της προσπάθειας του λειτουργικού συστήματος Copland της Apple) και είναι επί του παρόντος ανώτερος αρχιτέκτονας στο Excite. Σχεδίασε το Lucene για να διευκολύνει την προσθήκη ευρετηρίου και δυνατότητας αναζήτησης σε ένα ευρύ φάσμα εφαρμογών, όπως:

  • Email με δυνατότητα αναζήτησης: Μια εφαρμογή email θα επιτρέπει στους χρήστες να αναζητούν αρχειοθετημένα μηνύματα και να προσθέτουν νέα μηνύματα στο ευρετήριο κατά την άφιξή τους.
  • Αναζήτηση διαδικτυακής τεκμηρίωσης: Ένας αναγνώστης τεκμηρίωσης - που βασίζεται σε CD, βασίζεται στον Ιστό ή ενσωματώνεται στην εφαρμογή - θα μπορούσε να επιτρέψει στους χρήστες να αναζητήσουν διαδικτυακή τεκμηρίωση ή αρχειοθετημένες δημοσιεύσεις.
  • Ιστοσελίδες με δυνατότητα αναζήτησης: Ένα πρόγραμμα περιήγησης στο Web ή ένας διακομιστής μεσολάβησης θα μπορούσε να δημιουργήσει μια προσωπική μηχανή αναζήτησης για την ευρετηρίαση κάθε ιστοσελίδας που έχει επισκεφτεί ένας χρήστης, επιτρέποντας στους χρήστες να επισκέπτονται εύκολα τις σελίδες.
  • Αναζήτηση ιστότοπου: Ένα πρόγραμμα CGI θα μπορούσε να επιτρέψει στους χρήστες να κάνουν αναζήτηση στον ιστότοπό σας.
  • Αναζήτηση περιεχομένου: Μια εφαρμογή θα μπορούσε να επιτρέψει στον χρήστη να αναζητήσει αποθηκευμένα έγγραφα για συγκεκριμένο περιεχόμενο. Αυτό θα μπορούσε να ενσωματωθεί στο διάλογο Άνοιγμα εγγράφου.
  • Έλεγχος έκδοσης και διαχείριση περιεχομένου: Ένα σύστημα διαχείρισης εγγράφων θα μπορούσε να ευρετηριάσει έγγραφα ή εκδόσεις εγγράφων, ώστε να μπορούν να ανακτηθούν εύκολα.
  • Ροές ειδήσεων και καλωδίων: Ένας διακομιστής ειδήσεων ή ένα ρελέ θα μπορούσε να ευρετηριάσει άρθρα κατά την άφιξή τους.

Φυσικά, πολλές μηχανές αναζήτησης θα μπορούσαν να εκτελέσουν τις περισσότερες από αυτές τις λειτουργίες, αλλά λίγα εργαλεία αναζήτησης ανοιχτού κώδικα προσφέρουν την ευκολία στη χρήση, την ταχεία εφαρμογή και την ευελιξία του Lucene.

Χρησιμοποίησα για πρώτη φορά το Lucene κατά την ανάπτυξη του Eyebrowse, ενός εργαλείου ανοιχτού κώδικα Java για καταλογογράφηση και περιήγηση σε λίστες αλληλογραφίας. (Δείτε τους πόρους για έναν σύνδεσμο.) Βασική απαίτηση για το Eyebrowse ήταν η ευέλικτη δυνατότητα αναζήτησης και ανάκτησης μηνυμάτων. Απαίτησε ένα στοιχείο ευρετηρίου και αναζήτησης που θα ενημερώσει αποτελεσματικά τη βάση ευρετηρίου καθώς έφτασαν νέα μηνύματα, επιτρέποντας σε πολλούς χρήστες να αναζητούν και να ενημερώσουν τη βάση ευρετηρίου ταυτόχρονα και να κλιμακώσουν σε αρχεία που περιέχουν εκατομμύρια μηνύματα.

Κάθε άλλη μηχανή αναζήτησης ανοιχτού κώδικα που αξιολόγησα, συμπεριλαμβανομένων των Swish-E, Glimpse, iSearch και libibex, ταιριάζει ελάχιστα στις απαιτήσεις του Eyebrowse με κάποιο τρόπο. Αυτό θα έκανε την ενοποίηση προβληματική ή / και χρονοβόρα. Με το Lucene, πρόσθεσα ευρετηρίαση και αναζήτηση στο Eyebrowse σε λίγο περισσότερο από μισή ημέρα, από την αρχική λήψη έως τον κώδικα που λειτουργεί πλήρως! Αυτό ήταν λιγότερο από το ένα δέκατο του χρόνου ανάπτυξης που είχα προϋπολογιστεί και απέδωσε ένα πιο σφιχτά ενσωματωμένο και πλούσιο σε χαρακτηριστικά αποτέλεσμα από οποιοδήποτε άλλο εργαλείο αναζήτησης που θεωρούσα.

Πώς λειτουργούν οι μηχανές αναζήτησης

Δημιουργία και συντήρηση ενός ανεστραμμένος δείκτης είναι το κεντρικό πρόβλημα κατά τη δημιουργία μιας αποτελεσματικής μηχανής αναζήτησης λέξεων-κλειδιών. Για να ευρετηριάσετε ένα έγγραφο, πρέπει πρώτα να το σαρώσετε για να δημιουργήσετε μια λίστα με δημοσιεύσεις. Οι δημοσιεύσεις περιγράφουν τις εμφανίσεις μιας λέξης σε ένα έγγραφο. Περιλαμβάνουν γενικά τη λέξη, ένα αναγνωριστικό εγγράφου και ενδεχομένως τη θέση ή τις συχνότητες της λέξης μέσα στο έγγραφο.

Εάν σκέφτεστε τις δημοσιεύσεις ως πλειάδες της φόρμας , ένα σύνολο εγγράφων θα παράγει μια λίστα με καταχωρίσεις ταξινομημένες ανά αναγνωριστικό εγγράφου. Αλλά για να βρείτε αποτελεσματικά έγγραφα που περιέχουν συγκεκριμένες λέξεις, θα πρέπει αντ 'αυτού να ταξινομήσετε τις δημοσιεύσεις ανά λέξη (ή και από τη λέξη και από το έγγραφο, κάτι που θα κάνει τις αναζητήσεις πολλαπλών λέξεων πιο γρήγορες). Υπό αυτήν την έννοια, η δημιουργία ευρετηρίου αναζήτησης είναι βασικά ένα πρόβλημα ταξινόμησης. Το ευρετήριο αναζήτησης είναι μια λίστα δημοσιεύσεων ταξινομημένων κατά λέξη.

Μια καινοτόμος εφαρμογή

Οι περισσότερες μηχανές αναζήτησης χρησιμοποιούν B-tree για να διατηρήσουν το ευρετήριο. Είναι σχετικά σταθερές σε σχέση με την εισαγωγή και έχουν καλά συμπεριφερόμενα χαρακτηριστικά I / O (οι αναζητήσεις και οι εισαγωγές είναι λειτουργίες O (log n)). Το Lucene ακολουθεί μια ελαφρώς διαφορετική προσέγγιση: αντί να διατηρεί έναν μόνο δείκτη, δημιουργεί πολλά τμήματα ευρετηρίου και τα συγχωνεύει περιοδικά. Για κάθε νέο έγγραφο που έχει ευρετηριαστεί, η Lucene δημιουργεί ένα νέο τμήμα ευρετηρίου, αλλά συγχωνεύει γρήγορα μικρά τμήματα με μεγαλύτερα - αυτό διατηρεί τον συνολικό αριθμό τμημάτων μικρό, ώστε οι αναζητήσεις να παραμένουν γρήγορες. Για τη βελτιστοποίηση του ευρετηρίου για γρήγορη αναζήτηση, το Lucene μπορεί να συγχωνεύσει όλα τα τμήματα σε ένα, το οποίο είναι χρήσιμο για τα σπάνια ενημερωμένα ευρετήρια. Για να αποφευχθούν συγκρούσεις (ή να κλειδωθούν τα γενικά) μεταξύ αναγνωστών και συγγραφέων ευρετηρίου, η Lucene δεν τροποποιεί ποτέ τμήματα στη θέση της, δημιουργεί μόνο νέες. Όταν συγχωνεύει τμήματα, η Lucene γράφει ένα νέο τμήμα και διαγράφει τα παλιά - αφού το κλείσουν οι ενεργοί αναγνώστες. Αυτή η προσέγγιση κλιμακώνεται καλά, προσφέρει στον προγραμματιστή υψηλό βαθμό ευελιξίας στην ανταλλαγή ταχύτητας ευρετηρίου για ταχύτητα αναζήτησης και έχει επιθυμητά χαρακτηριστικά εισόδου / εξόδου τόσο για συγχώνευση όσο και για αναζήτηση.

Ένα τμήμα ευρετηρίου Lucene αποτελείται από πολλά αρχεία:

  • Ευρετήριο λεξικού που περιέχει μία καταχώριση για κάθε 100 καταχωρήσεις στο λεξικό
  • Ένα λεξικό που περιέχει μία καταχώριση για κάθε μοναδική λέξη
  • Ένα αρχείο δημοσιεύσεων που περιέχει μια καταχώριση για κάθε ανάρτηση

Δεδομένου ότι η Lucene δεν ενημερώνει ποτέ τμήματα στη θέση τους, μπορούν να αποθηκευτούν σε επίπεδα αρχεία αντί για περίπλοκα B-tree. Για γρήγορη ανάκτηση, το ευρετήριο λεξικού περιέχει αντισταθμίσεις στο αρχείο λεξικού και το λεξικό διατηρεί αντισταθμίσεις στο αρχείο δημοσιεύσεων. Το Lucene εφαρμόζει επίσης μια ποικιλία από κόλπα για τη συμπίεση του λεξικού και την ανάρτηση αρχείων - μειώνοντας έτσι το I / O του δίσκου - χωρίς να υπάρξει σημαντική επιβάρυνση της CPU.

Αξιολόγηση μηχανών αναζήτησης

Άλλες ευρέως χρησιμοποιούμενες μηχανές αναζήτησης ανοιχτού κώδικα περιλαμβάνουν Swish-E, Glimpse, libibex, freeWAIS και iSearch. Όπως κάθε πακέτο λογισμικού, το καθένα είναι βελτιστοποιημένο για χρήση σε συγκεκριμένες καταστάσεις. Είναι συχνά δύσκολο να αναπτυχθούν αυτά τα εργαλεία εκτός των τομέων που προορίζονται. Εξετάστε τις ακόλουθες δυνατότητες κατά την αξιολόγηση μιας μηχανής αναζήτησης:

  • Αύξηση έναντι παρτίδας ευρετηρίαση: Ορισμένες μηχανές αναζήτησης υποστηρίζουν μόνο ευρετηρίαση παρτίδων. Μόλις δημιουργήσουν ένα ευρετήριο για ένα σύνολο εγγράφων, η προσθήκη νέων εγγράφων καθίσταται δύσκολη χωρίς την επαναπροσάρτηση όλων των εγγράφων. Η σταδιακή ευρετηρίαση επιτρέπει την εύκολη προσθήκη εγγράφων σε υπάρχον ευρετήριο. Για ορισμένες εφαρμογές, όπως αυτές που χειρίζονται ροές ζωντανών δεδομένων, η αυξητική ευρετηρίαση είναι κρίσιμη. Το Lucene υποστηρίζει και τους δύο τύπους ευρετηρίασης.
  • Πηγές δεδομένων: Πολλές μηχανές αναζήτησης μπορούν να ευρετηριάσουν μόνο αρχεία ή ιστοσελίδες. Αυτό το μειονέκτημα εφαρμογών όπου τα δεδομένα ευρετηρίου προέρχονται από μια βάση δεδομένων ή όπου υπάρχουν πολλά εικονικά έγγραφα σε ένα αρχείο, όπως ένα αρχείο ZIP. Το Lucene επιτρέπει στους προγραμματιστές να παραδώσουν το έγγραφο στον ευρετήριο μέσω ενός Σειρά ή ένα InputStream, επιτρέποντας την εξαγωγή της πηγής δεδομένων από τα δεδομένα. Ωστόσο, με αυτήν την προσέγγιση, ο προγραμματιστής πρέπει να παρέχει τους κατάλληλους αναγνώστες για τα δεδομένα.
  • Έλεγχος ευρετηρίου: Ορισμένες μηχανές αναζήτησης μπορούν αυτόματα να ανιχνεύσουν μέσω ενός δέντρου καταλόγου ή ενός ιστότοπου για να βρουν έγγραφα για ευρετήριο. Αν και αυτό είναι βολικό εάν τα δεδομένα σας είναι ήδη αποθηκευμένα με αυτόν τον τρόπο, οι δείκτες που βασίζονται σε πρόγραμμα ανίχνευσης συχνά παρέχουν περιορισμένη ευελιξία για εφαρμογές που απαιτούν λεπτομερή έλεγχο των ευρετηριασμένων εγγράφων. Δεδομένου ότι το Lucene λειτουργεί κυρίως σε αυξητική λειτουργία, επιτρέπει στην εφαρμογή να βρει και να ανακτήσει έγγραφα.
  • Μορφές αρχείων: Ορισμένες μηχανές αναζήτησης μπορούν να ευρετηριάσουν μόνο κείμενο ή έγγραφα HTML. Άλλοι υποστηρίζουν έναν μηχανισμό φίλτρου, ο οποίος προσφέρει μια απλή εναλλακτική λύση για την ευρετηρίαση εγγράφων επεξεργασίας κειμένου, εγγράφων SGML και άλλων μορφών αρχείων. Το Lucene υποστηρίζει έναν τέτοιο μηχανισμό.
  • Επισήμανση περιεχομένου: Ορισμένες μηχανές αναζήτησης αντιμετωπίζουν ένα έγγραφο ως μια μοναδική ροή διακριτικών. Άλλοι επιτρέπουν τον προσδιορισμό πολλαπλών πεδίων δεδομένων σε ένα έγγραφο, όπως "θέμα", "αφηρημένο", "συγγραφέας" και "σώμα". Αυτό επιτρέπει σημασιολογικά πλουσιότερα ερωτήματα όπως "συγγραφέας περιέχει Χάμιλτον ΚΑΙ σώμα περιέχει Σύνταγμα. "Το Lucene υποστηρίζει την προσθήκη ετικετών περιεχομένου αντιμετωπίζοντας τα έγγραφα ως συλλογές πεδίων και υποστηρίζει ερωτήματα που καθορίζουν ποια πεδία θα αναζητούν.
  • Διακοπή επεξεργασίας κειμένου: Κοινές λέξεις, όπως "a," "και", "και" the ", προσθέτουν μικρή αξία σε ένα ευρετήριο αναζήτησης. Αλλά επειδή αυτές οι λέξεις είναι τόσο συχνές, η καταλογογράφηση τους θα συμβάλει σημαντικά στον χρόνο ευρετηρίου και στο μέγεθος ευρετηρίου. Οι περισσότερες μηχανές αναζήτησης δεν θα ευρετηριάσουν συγκεκριμένες λέξεις σταματήστε τα λόγια. Ορισμένοι χρησιμοποιούν μια λίστα λέξεων διακοπής, ενώ άλλοι επιλέγουν στατιστικά τις λέξεις διακοπής. Η Lucene χειρίζεται τις λέξεις διακοπής με τις πιο γενικές Αναλυτής μηχανισμό, που θα περιγραφεί αργότερα, και παρέχει το Διακοπή ανάλυσης τάξη, η οποία εξαλείφει τις λέξεις διακοπής από τη ροή εισόδου.
  • Προέλευση: Συχνά, ένας χρήστης επιθυμεί ένα ερώτημα για μια λέξη να ταιριάζει με άλλες παρόμοιες λέξεις. Για παράδειγμα, ένα ερώτημα για "άλμα" θα πρέπει πιθανώς να αντιστοιχεί και στις λέξεις "άλμα", "άλτης" ή "άλματα". Η μείωση μιας λέξης στη ριζική της μορφή ονομάζεται βγαίνει. Το Lucene δεν εφαρμόζει ακόμα το stemming, αλλά θα μπορούσατε εύκολα να προσθέσετε ένα stemmer μέσω ενός πιο εξελιγμένου Αναλυτής τάξη.
  • Χαρακτηριστικά ερωτήματος: Οι μηχανές αναζήτησης υποστηρίζουν μια ποικιλία λειτουργιών ερωτημάτων. Ορισμένα υποστηρίζουν πλήρη ερωτήματα Boolean. άλλοι υποστηρίζουν μόνο και ερωτήματα. Ορισμένοι επιστρέφουν ένα σκορ "σχετικότητας" με κάθε επιτυχία. Μερικοί μπορούν να χειριστούν ερωτήματα γειτνίασης ή εγγύτητας - αναζήτηση ακολουθούμενη από κινητήρας "ή" Knicks κοντά Celtics "- άλλοι μπορούν να κάνουν αναζήτηση μόνο σε μεμονωμένες λέξεις-κλειδιά. Ορισμένοι μπορούν να αναζητήσουν πολλαπλά ευρετήρια ταυτόχρονα και να συγχωνεύσουν τα αποτελέσματα για να δώσουν μια σημαντική βαθμολογία συνάφειας. Το Lucene υποστηρίζει ένα ευρύ φάσμα λειτουργιών ερωτημάτων, συμπεριλαμβανομένων όλων αυτών που αναφέρονται παραπάνω. Ωστόσο, το Lucene κάνει δεν υποστηρίζει το πολύτιμο Soundex ή "ακούγεται σαν" ερώτημα.
  • Συγχρονισμός: Μπορούν πολλοί χρήστες να αναζητήσουν ένα ευρετήριο ταυτόχρονα; Μπορεί ένας χρήστης να αναζητήσει ένα ευρετήριο ενώ ένας άλλος το ενημερώνει; Το Lucene επιτρέπει στους χρήστες να αναζητούν ένα ευρετήριο συναλλακτικά, ακόμη και αν άλλος χρήστης ενημερώνει ταυτόχρονα το ευρετήριο.
  • Μη αγγλική υποστήριξη: Πολλές μηχανές αναζήτησης υποθέτουν σιωπηρά ότι τα αγγλικά είναι η γλώσσα στόχος. Αυτό είναι εμφανές σε τομείς όπως λίστες διακοπής λέξεων, αλγόριθμοι βλαβών και χρήση της εγγύτητας για αντιστοίχιση ερωτημάτων φράσης. Καθώς το Lucene προεπεξεργάζεται τη ροή εισόδου μέσω του Αναλυτής τάξη που παρέχεται από τον προγραμματιστή, είναι δυνατό να πραγματοποιηθεί φιλτράρισμα για συγκεκριμένη γλώσσα.

Αν και σε καμία περίπτωση δεν είναι εξαντλητική, η παραπάνω λίστα προσφέρει ένα σημείο εκκίνησης για την αξιολόγηση μιας μηχανής αναζήτησης για ένα συγκεκριμένο έργο. Ορισμένα εργαλεία αναζήτησης δεν είναι κατάλληλα για συγκεκριμένες εργασίες - η κατανόηση των απαιτήσεων της εφαρμογής σας μπορεί να σας βοηθήσει να επιλέξετε το σωστό εργαλείο για την εργασία.

Χρησιμοποιώντας το Lucene

Θα επεξηγήσω πώς να χρησιμοποιώ το Lucene για τη δημιουργία, τη συμπλήρωση και την αναζήτηση ενός ευρετηρίου. Για λόγους σαφήνειας, οι δηλώσεις εισαγωγής και ο χειρισμός εξαιρέσεων έχουν παραλειφθεί από τα δείγματα προγραμμάτων. Σε αυτές τις εικόνες, έχω αποθηκεύσει το ευρετήριο αναζήτησης στο σύστημα αρχείων (μπορείτε να αποθηκεύσετε ευρετήρια οπουδήποτε, π.χ. στη μνήμη ή σε μια βάση δεδομένων). Τα αρχεία που ευρετηριάζονται είναι απλά αρχεία κειμένου. Με το Lucene, μπορείτε επίσης να ευρετηριάσετε εύκολα άλλες μορφές εγγράφων και έγγραφα που δεν είναι αποθηκευμένα σε αρχεία.

Δημιουργήστε ένα ευρετήριο

Το απλό πρόγραμμα ΔημιουργίαIndex.java δημιουργεί ένα κενό ευρετήριο δημιουργώντας ένα IndexWriter αντικείμενο και καθοδηγώντας το να δημιουργήσει ένα κενό ευρετήριο. Σε αυτό το παράδειγμα, το όνομα του καταλόγου που θα αποθηκεύσει το ευρετήριο καθορίζεται στη γραμμή εντολών.

δημόσια κλάση CreateIndex {// use: CreateIndex ευρετήριο ευρετηρίου δημόσιου στατικού κενού main (String [] args) ρίχνει την Εξαίρεση {String indexPath = args [0]; Συγγραφέας IndexWriter; // Δημιουργείται ένα ευρετήριο ανοίγοντας ένα IndexWriter με το όρισμα // create να είναι true. author = new IndexWriter (indexPath, null, true); author.close (); }} 

Ευρετήριο κειμένων εγγράφων

IndexFile.java δείχνει πώς να προσθέσετε έγγραφα - τα αρχεία που αναφέρονται στη γραμμή εντολών - σε ένα ευρετήριο. Για κάθε αρχείο, Αρχεία ευρετηρίου δημιουργεί ένα Εγγραφο αντικείμενο και, στη συνέχεια, καλεί IndexWriter.addDocument για να το προσθέσετε στο ευρετήριο. Από τη σκοπιά του Λουκένιου, α Εγγραφο είναι μια συλλογή πεδίων που είναι ζεύγη τιμών-τιμών. ΕΝΑ Πεδίο μπορεί να αποκτήσει την αξία του από ένα Σειρά, για σύντομα πεδία ή InputStream, για μεγάλα πεδία. Η χρήση πεδίων σάς επιτρέπει να διαχωρίσετε ένα έγγραφο σε ξεχωριστά τμήματα με δυνατότητα αναζήτησης και ευρετηρίασης και να συσχετίσετε μεταδεδομένα - όπως όνομα, συντάκτης ή ημερομηνία τροποποίησης - με ένα έγγραφο. Για παράδειγμα, κατά την αποθήκευση μηνυμάτων αλληλογραφίας, θα μπορούσατε να βάλετε το θέμα, τον συντάκτη, την ημερομηνία και το σώμα ενός μηνύματος σε ξεχωριστά πεδία και, στη συνέχεια, να δημιουργήσετε σημασιολογικά πιο πλούσια ερωτήματα όπως το θέμα περιέχει Ιάβα ΚΑΙ συντάκτης περιέχει Χηνάρι. "Στον παρακάτω κώδικα, αποθηκεύουμε δύο πεδία σε κάθε ένα Εγγραφο: μονοπάτι, για να προσδιορίσετε την αρχική διαδρομή αρχείου, ώστε να μπορεί να ανακτηθεί αργότερα και σώμα, για τα περιεχόμενα του αρχείου.

δημόσια κλάση IndexFiles {// use: IndexFiles index-path file. . . public static void main (String [] args) ρίχνει την Εξαίρεση {String indexPath = args [0]; Συγγραφέας IndexWriter; author = new IndexWriter (indexPath, new SimpleAnalyzer (), false); για (int i = 1; i
$config[zx-auto] not found$config[zx-overlay] not found