Posted by Χρίστος Ευαγγέλου Sun, 14 Jun 2009 12:48:53 EEST
Την περασμένη εβδομάδα είχα να αντιμετωπίσω ένα ενδιαφέρον πρόβλημα.
Χρησιμοποιώ μια εφαρμογή η οποία παράγει αρχεία (logs) απλού κειμένου, το μέγεθος των οποίων φτάνει καθημερινά (περίπου) το 0.5 GB. Η αποθήκευση δεν είναι πρόβλημα επειδή όταν συμπιεστούν, τα logs μιας μέρας πέφτουν στα 10-20 MB.
Ιδού λοιπόν το πρόβλημα: Συχνά ψάχνω στα logs για να βρω κάποιο κείμενο χρησιμοποιώντας το κλασικό εργαλείο grep του Unix. Αυτό δεν θα ήταν και τόσο πρόβλημα αν διατηρούνταν logs μονάχα για 2-3 μέρες. Εντούτοις, τα logs αυτά διατηρούνται για πολλούς μήνες. Ενδεικτικά, σε ένα μήνα έχουμε περίπου 0.5 * 30 = 15 GB πληροφορίας. Το ψάξιμο με grep (ή με οποιοδήποτε άλλο παρόμοιο εργαλείο αναζήτησης) σε τέτοιο όγκο δεδομένων είναι χρονοβόρο και άρα μη πρακτικό.
Ψάχνοντας λοιπόν, βρήκα ένα open-source εργαλείο το οποίο λέγεται swish-e. Το εργαλείο αυτό, είναι στην ουσία ένας command-line indexer: διαβάζει ένα σύνολο αρχείων και φτιάχνει ένα "πίνακα περιεχομένων" (index), επιτρέποντας έτσι την πολύ γρήγορη αναζήτηση πληροφορίας. Είπα, λοιπόν, να το δοκιμάσω.
Εγκατάσταση
Ξεκίνησα κατεβάζοντας το source-code από την σχετική σελίδα (σημείωση: binaries για Windows υπάρχουν στην ίδια σελίδα).
Αποσυμπίεσα λοιπόν το tarball και έκανα την κλασική διαδικασία που κάνει κάποιος όταν χρειάζεται να κάνει compile από source (configure, make, make install)*:
Έτρεξα το configure script για να φτιάξει τα makefiles:
Λίγα δευτερόλεπτα μετά, το configure τελείωσε, και ήμουν έτοιμος να μεταγλωττίσω. Έτρεξα λοιπόν την make. Μετά από ένα λεπτό περίπου, η μεταγλώττιση τελείωσε επιτυχώς.
Τέλος, έτρεξα το make install για να αντιγράψει τα binary αρχεία που δημιουργήθηκαν κατά την μεταγλώττιση στα σωστά directories.
Αυτό ήταν! Πάμε λοιπόν να το δοκιμάσουμε τώρα.
Δημιουργία Ευρετηρίου
Το πρώτο βήμα είναι η δημιουργία του ευρετηρίου. Αυτό γίνεται με την εντολή "swish-e -i":
Η επιλογή -i υποδηλώνει για πια directories ή αρχεία θέλουμε να φτιάξουμε ευρετήριο. Στην περίπτωση μας, είναι το directory /usr/src. Η επιλογή -f υποδηλώνει το όνομα και τοποθεσία του αρχείου-ευρετηρίου το οποίο θα δημιουργηθεί. Αν δεν δοθεί, το ευρετήριο θα δημιουργηθεί στο directory από όπου εκτελείται η εντολή και θα έχει όνομα "index.swish-e".
Τα αποτελέσματα δεν φαίνονταν και πολύ καλά: Υπήρχαν πολλά μηνύματα λάθους, όπως φαίνεται πιο κάτω. Το swish-e δυσκολευόταν να καταλάβει τα περιεχόμενα των διάφορων αρχείων:
Ψάχνοντας λιγάκι, κατάλαβα γιατί συμβαίνει αυτό: Εξορισμού, το swish-e υποθέτει ότι τα αρχεία τα οποία επεξεργαζόμαστε περιέχουν κώδικα HTML. Επειδή όμως τα περισσότερα αρχεία κάτω από το /usr/src δεν είναι σε τέτοια μορφή, το swish-e παραπονιόταν.
Αρχείο Ρυθμίσεων
Η λύση ήταν απλή: Το swish-e μπορεί να διαβάσει τις ρυθμίσεις του από ένα αρχείο ρυθμίσεων (configuration file). Εκεί μπορείς να του υποδηλώσεις σε τι μορφή να υποθέσει ότι είναι τα αρχεία εισόδου. Έφτιαξα λοιπόν ένα αρχείο ρυθμίσεων και χρησιμοποίησα την ρύθμιση DefaultContents για να αναγκάσω το swish-e να μεταχειριστεί τα περιεχόμενα των αρχείων εισόδου ως αρχεία απλού κειμένου:
Εκτός από TXT, υποστηρίζονται επίσης XML και HTML. Μπορούμε να υποδηλώσουμε την μορφή των αρχείων με βάση το extension τους χρησιμοποιώντας το IndexContents. Για παράδειγμα:
Εάν ένα αρχείο δεν έχει extension που να ταιριάζει με κάποιο IndexContents, θα τύχει χειρισμού σύμφωνα με την επιλογή στο DefaultContents.
To swish-e υποστηρίζει τις ακόλουθες μορφές:
Σημείωση: Δεν έκανα δοκιμές για να δω πιο parser είναι πιο γρήγορο.
Δοκιμή
Έτρεξα λοιπόν ξανά το swish-e, λέγοντας του να χρησιμοποιήσει το configuration file το οποίο έφτιαξα μέσω της επιλογής -c. Η διαδικασία ολοκληρώθηκε επιτυχώς μέσα σε περίπου 3.5 λεπτά:
Περίπου, λοιπόν, 440 MB έγιναν index σε 3.5 λεπτά. Το index file ήτανε περίπου 130 MB. Δεν ήτανε και άσχημα.
Πάμε λοιπόν να ψάξουμε για την φράση what the hell. Για ψάξιμο, χρησιμοποιείται η επιλογή -w, ακολουθούμενη από λέξεις ή φράσεις οι οποίες θα αναζητηθούν.
Σημείωση: το swish-e υποστηρίζει πληθώρα μορφών αναζήτησης, μεταξύ των οποίων αναζήτηση λέξεων, φράσεων, τελεστές boolean, wildcards κλπ. Πληρέστερη περιγραφή εδώ.
Η αναζήτηση πήρε περίπου 0.065 δευτερόλεπτα. Καθόλου άσχημα.
Το swish-e μας ενημερώνει τον βαθμό κατάταξης (ranking) του κάθε αρχείου το οποίο περιέχει τον όρο αναζήτησης, την τοποθεσία και το όνομα του, και το μέγεθος του. Η μορφή εξόδου μπορεί να διαμορφωθεί από τον χρήστη, είτε μέσω του configuration file, είτε μέσω της επιλογής -x.
Αρχεία με υψηλότερη κατάταξη περιέχουν τον όρο περισσότερες φορές από ότι τα αρχεία με χαμηλότερη κατάταξη.
Φιλτράρισμα Εισόδου
Ωραία. Φαινόταν ότι το swish-e κάνει την δουλειά που ήθελα. Υπήρχε όμως ακόμη ένα σημείο το οποίο ήθελα να ερευνήσω: πολλά από τα αρχεία τα οποία θα πρέπει να γίνουν index θα είναι συμπιεσμένα. Μπορεί το swish-e να χειριστεί συμπιεσμένα αρχεία;
Η απάντηση ήταν ναι! Μέσω του αρχείου ρυθμίσεων, μπορείς να ζητήσεις από το swish-e να περάσει ορισμένα αρχεία εισόδου από κάποια άλλη εφαρμογή (φίλτρο), πριν τύχουν επεξεργασίας από το swish-e. Αυτό επιτυγχάνεται μέσω της ρύθμισης FileFilter.
Στην δική μου περίπτωση, ήξερα ότι κάποια αρχεία θα είναι συμπιεσμένα με bzip2 ή gzip. Για αυτό λοιπόν, πρόσθεσα στο αρχείο ρυθμίσεων τις ακόλουθες δύο γραμμές:
Με αυτό τον τρόπο, ζητώ από το swish-e όταν βρει αρχεία με επέκταση .bz2 ή .gz, να τρέξει την εντολή bzcat και gzcat αντίστοιχα, περνώντας το όνομα του αρχείου (αυτό λέει το %p) ως παράμετρο. Το swish-e παίρνει την έξοδο από το τρέξιμο της εντολής (στην περίπτωση μας θα είναι τα περιεχόμενα του αποσυμπιεσμένου αρχείου) και την χρησιμοποιεί για να φτιάξει το index.
Αυτό λοιπόν ήταν το swish-e: ένα ισχυρό εργαλείο δημιουργίας ευρετηρίων αναζήτησης για αρχεία κειμένου, HTML και XML.
Στην δημοσίευση ανέφερα πολύ επιφανειακά κάποια βασικά χαρακτηριστικά του. Για μια πληρέστερη εικόνα, μπορείτε να ανατρέξετε εδώ:
Να αναφέρω επίσης ότι δοκίμασα το σύστημα (μεταγλώττιση, κτίσιμο index και αναζήτηση) στις ακόλουθες πλατφόρμες:
Ελπίζω να φανεί χρήσιμο και σε μερικούς από εσάς.
*Τα βήματα διαφέρουν από εφαρμογή σε εφαρμογή. Οι ενδιαφερώμενοι θα πρέπει να ανατρέξουν στις οδηγίες μεταγλώττισης του εκάστοτε πακέτου, οι οποίες συνήθως παρέχονται μαζί με τον κώδικα.
2 comments
Ευχαριστούμε για την πολύ χρήσιμη ενημέρωση! Ίσως κάποτε το χρειαστώ αυτό το εργαλείο. :)
χρήσιμο, ευχαριστούμε!