Per semplificare:non esiste un modo rapido per aprire, cercare e chiudere 600.000 documenti ogni volta che si desidera eseguire una ricerca. I tuoi benchmark con "oltre un minuto" sono probabilmente con account di prova singoli. Se prevedi di cercarli tramite un sito Web multiutente, puoi dimenticartene rapidamente, perché il tuo disk IO
sarà fuori classifica e bloccherà l'intero server.
Quindi le tue uniche opzioni sono indicizzare tutti i file. Proprio come fa qualsiasi altra utilità di ricerca rapida. Non importa se usi Solr o ElasticSearch come menzionato nei commenti o costruisci qualcosa di tuo. I file verranno indicizzati.
Considerando il txt
i file sono versioni testuali di pdf
file che ricevi, scommetto che la soluzione più semplice è scrivere il testo in un database anziché in un file. Non occuperà comunque molto più spazio su disco.
Quindi puoi abilitare full text search
sul tuo database (mysql
, mssql
e altri lo supportano) e sono sicuro che i tempi di risposta saranno molto migliori. Tieni presente che la creazione di questi indexes
richiedono spazio di archiviazione, ma lo stesso vale per altre soluzioni.
Ora, se vuoi davvero velocizzare le cose, puoi provare ad analizzare i curriculum a un livello più dettagliato. Prova a recuperare luoghi, istruzione, lingue parlate e altre informazioni che cerchi regolarmente e inseriscile in tabelle/colonne separate. Questo è un compito molto difficile e quasi un progetto a sé stante, ma se vuoi un risultato di ricerca prezioso, questa è la strada da percorrere. Poiché la ricerca nel testo senza contesto fornisce risultati molto diversi, basti pensare al tuo esempio "new york":
- Vivo a New York
- Ho studiato alla New York University
- Adoro la canzone "new york" di Alicia Keys in una biografia personale
- Ho lavorato per New York Pizza
- Sono nato nel New Yorkshire, nel Regno Unito
- Ho passato un'estate ad allevare new yorkshire terrier.
Non andrò troppo in profondità, ma cercherò di fornire linee guida per la creazione di un proof of concept.
1
Prima scarica ed estrai la ricerca elastica da qui:https://www.elastic.co/downloads/elasticsearch e poi eseguila:
bin/elasticsearch
2
Scarica https://github.com/dadoonet/fscrawler#download-fscrawler estrailo ed eseguilo:
bin/fscrawler myCustomJob
Quindi fermalo (Ctrl-C) e modifica il corrispondente myCustomJob/_settings.json
(È stato creato automaticamente e il percorso è stato stampato sulla console).
Puoi modificare le proprietà:"url"
(percorso da scansionare),"update_rate"
(puoi renderlo 1m
),"includes"
(ad es. ["*.pdf","*.doc","*.txt"]
), "index_content"
(rendilo falso, per rimanere solo sul nome del file).
Esegui di nuovo:
bin/fscrawler myCustomJob
Nota:l'indicizzazione è qualcosa che potresti voler eseguire in seguito utilizzando il codice, ma per ora verrà eseguita automaticamente, utilizzando fscrawler
, che comunica direttamente con elastic.
3
Ora inizia ad aggiungere file alla directory che hai specificato in "url"
proprietà.
4
Scarica il client di riposo avanzato per Chrome e crea il seguente POST
:
URL:http://localhost:9200/_search
Carico utile grezzo:
{
"query": { "wildcard": {"file.filename":"aFileNameToSearchFor*"} }
}
Otterrai di nuovo l'elenco dei file corrispondenti. Nota:fscrawler
sta indicizzando i nomi dei file sotto la chiave:file.filename
.
5
Ora, invece di utilizzare il client di riposo avanzato puoi usare PHP per eseguire questa query. O tramite una chiamata REST all'URL sopra o utilizzando l'API php-client:https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/_search_operations.html
Lo stesso vale per l'indicizzazione:https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/_indexing_documents.html
Se vuoi salvare tutte le informazioni sui file nel database:
<?php
function deep_scandir( $dir, &$query, &$files) {
$count = 0;
if(is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($item = readdir($dh)) !== false) {
if($item != '.' && $item != '..') {
if(is_dir($dir.'/'.$item)){
deep_scandir($dir.'/'.$item, $query, $files);
}else{
$count++;
preg_match("/(\d\_\d+)\_(.*)\.txt/i", $item, $matches);
if(!empty($matches)){
$no = $matches[1];
$str = $matches[2];
$files[$dir][$no] = $str;
$content = addcslashes( htmlspecialchars( file_get_contents($dir.'/'.$item) ), "\\\'\"" );
$query[] = "INSERT INTO `mytable` (id, key, value, path, content)
VALUES\n(NULL, '$no', '$str', '$dir/$item', '$content');";
}
}
}
}
closedir($dh);
}
}
return $count;
}
echo '<pre>';
$dir = 'notes_docs/files_txt';
$query = [];
$files = [];
echo deep_scandir($dir, $query, $files);
echo '<br>';
print_r($files);
echo '<br>';
print_r($query);
Ora puoi eseguire ogni riga nell'array
foreach($query as $no=>$line){
mysql_query($line) or trigger_error("Couldn't execute query no: '$no' [$line]");
}
Uscita:
Array
(
[notes_docs/files_txt/20170831] => Array
(
[1_291838733] => uridjdh
[1_482737439] => a8weele
[1_579374743] => abc2_file
[1_733839474] => dejsde
[1_837837472] => abc_file
)
)
Array
(
[0] => INSERT INTO `mytable` (id, key, value, path, content)
VALUES
(NULL, '1_291838733', 'uridjdh', 'notes_docs/files_txt/20170831/1_291838733_uridjdh.txt', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus in nisl quis lectus sagittis ullamcorper at faucibus urna. Suspendisse tristique arcu sit amet ligula cursus pretium vitae eu elit. Nullam sed dolor ornare ex lobortis posuere. Quisque venenatis laoreet diam, in imperdiet arcu fermentum eu. Aenean molestie ligula id sem ultricies aliquet non a velit. Proin suscipit interdum vulputate. Nullam finibus gravida est, et fermentum est cursus eu. Integer sed metus ac urna molestie finibus. Aenean hendrerit ante quis diam ultrices pellentesque. Duis luctus turpis id ipsum dictum accumsan. Curabitur ornare nisi ligula, non pretium nulla venenatis sed. Aenean pharetra odio nec mi aliquam molestie. Fusce a condimentum nisl. Quisque mattis, nulla suscipit condimentum finibus, leo ex eleifend felis, vel efficitur eros turpis nec sem. ');
[1] => INSERT INTO `mytable` (id, key, value, path, content)
VALUES
(NULL, '1_482737439', 'a8weele', 'notes_docs/files_txt/20170831/1_482737439_a8weele.txt', 'Nunc et odio sed odio rhoncus venenatis congue non nulla. Aliquam dictum, felis ac aliquam luctus, purus mi dignissim magna, vitae pharetra risus elit ac mi. Sed sodales dui semper commodo iaculis. Nunc vitae neque ut arcu gravida commodo. Fusce feugiat velit et felis pharetra posuere sit amet sit amet neque. Phasellus iaculis turpis odio, non consequat nunc consectetur a. Praesent ornare nisi non accumsan bibendum. Nunc vel ultricies enim, consectetur fermentum nisl. Sed eu augue ac massa efficitur ullamcorper. Ut hendrerit nisi arcu, a sagittis velit viverra ac. Quisque cursus nunc ac tincidunt sollicitudin. Cras eu rhoncus ante, ac varius velit. Mauris nibh lorem, viverra in porttitor at, interdum vel elit. Aliquam imperdiet lacus eu mi tincidunt volutpat. Vestibulum ut dolor risus. ');
[2] => INSERT INTO `mytable` (id, key, value, path, content)
VALUES
(NULL, '1_579374743', 'abc2_file', 'notes_docs/files_txt/20170831/1_579374743_abc2_file.txt', 'Vivamus aliquet id elit vitae blandit. Proin laoreet ipsum sed tincidunt commodo. Fusce faucibus quam quam, in ornare ex fermentum et. Suspendisse dignissim, tortor at fringilla tempus, nibh lacus pretium metus, vel tempus dolor tellus ac orci. Vestibulum in congue dolor, nec porta elit. Donec pellentesque, neque sed commodo blandit, augue sapien dapibus arcu, sit amet hendrerit felis libero id ante. Praesent vitae elit at eros faucibus volutpat. Integer rutrum augue laoreet ex porta, ut faucibus elit accumsan. Donec in neque sagittis, auctor diam ac, viverra diam. Phasellus vel quam dolor. Nullam nisi tellus, faucibus a finibus et, blandit ac nisl. Vestibulum interdum malesuada sem, nec semper mi placerat quis. Nullam non bibendum sem, vitae elementum metus. Donec non ipsum quis turpis semper lobortis.');
[3] => INSERT INTO `mytable` (id, key, value, path, content)
VALUES
(NULL, '1_733839474', 'dejsde', 'notes_docs/files_txt/20170831/1_733839474_dejsde.txt', 'Nunc faucibus, enim non luctus rutrum, lorem urna finibus turpis, sit amet dictum turpis ipsum pharetra ex. Donec at leo vitae massa consectetur viverra eget vel diam. Sed in neque tempor, vulputate quam sed, ullamcorper nisl. Fusce mollis libero in metus tincidunt interdum. Cras tempus porttitor nunc nec dapibus. Vestibulum condimentum, nisl eget venenatis tincidunt, nunc sem placerat dui, quis luctus nisl erat sed orci. Maecenas maximus finibus magna in facilisis. Maecenas maximus turpis eget dignissim fermentum. ');
[4] => INSERT INTO `mytable` (id, key, value, path, content)
VALUES
(NULL, '1_837837472', 'abc_file', 'notes_docs/files_txt/20170831/1_837837472_abc_file.txt', 'Integer non ex condimentum, aliquet lectus id, accumsan nibh. Quisque aliquet, ante vitae convallis ullamcorper, velit diam tempus diam, et accumsan metus eros at tellus. Sed lacinia mauris sem, scelerisque efficitur mauris aliquam a. Nullam non auctor leo. In mattis mauris eu blandit varius. Phasellus interdum mi nec enim imperdiet tristique. In nec porttitor erat, tempor malesuada ante. Etiam scelerisque ligula et ex maximus, placerat consequat nunc consectetur. Phasellus suscipit ligula sed elit hendrerit laoreet. Suspendisse ex sem, placerat pharetra ligula eu, accumsan rhoncus ex. Sed luctus nisi vitae metus maximus scelerisque. Suspendisse porta nibh eget placerat tempus. Nunc efficitur gravida sagittis. ');
)