2012-08-06 15 views
16

Esiste una libreria JavaScript che può determinare se una stringa corrisponde a una query di ricerca? Dovrebbe essere efficiente e fornire funzionalità di query avanzate come quella di Google o LexisNexis (cose come e/o operatori, sinonimi e parentesi). Qualsiasi tipo di funzionalità di ricerca avanzata sarebbe fantastico; non deve essere una corrispondenza esatta con un particolare motore di ricerca.Libreria JavaScript per la ricerca di stili del motore di ricerca?

Motivazione: ho una pagina HTML con una casella di ricerca seguita da un gruppo di paragrafi (che hanno ID univoci e sono generati da un array JavaScript). Quando l'utente digita una query di ricerca nella casella e preme Invio, tutti i paragrafi devono essere nascosti (ad esempio, il loro display impostato su none) se non corrispondono alla query.

La mia strategia attuale (usando jQuery):

  1. separata la stringa di query in un array di parole chiave dividendo sopra spazio bianco.
  2. Nascondere tutti i paragrafi con $('p').hide().
  3. Per ogni parola chiave, mostra un paragrafo che lo contiene con $('p:contains("'+keyword+'")').show().

che è una funzione di ricerca estremamente limitata che è case-sensitive, tratta tutte le parole chiave come optional, e non fornisce operatori come and, or, o parentesi. È anche inefficiente perché passa attraverso ogni stringa una volta per ogni parola chiave, anche se è già stata abbinata.

+0

per rendere la distinzione tra maiuscole e minuscole, è possibile convertire la parola chiave in minuscolo e verificare la corrispondenza i, e. keyword.toLowerCase() – Shreedhar

risposta

27

Ecco alcune librerie che sto valutando per i progetti (a luglio 2013). Ognuno di questi dovrebbe essere in grado di fornire il nucleo della funzione di ricerca.

Se avete voglia di costruire il proprio, qui ci sono implementazioni di 2 algoritmi derivanti comuni per iniziare:

Come per la gestione degli operatori di ricerca logica booleana, forse this question about js query parsers sarà essere utile.

+0

Grazie per aver condiviso questo, mi chiedevo con chi si fosse deciso e se avessi qualche soluzione migliorata da aggiungere nel 2017? – Noitidart

+2

@Noitidart Non ho avuto bisogno di questi sistemi da un po 'di tempo in quello su cui stavo lavorando, ma se avessi intenzione di fare qualcosa oggi la mia prima scelta sarebbe ancora la stessa di allora: lunrjs – turtlemonvh

+0

Grazie @Turtlemonvh Lo apprezzo! – Noitidart

2

il modo migliore (facile e buona) è quello di utilizzare vettore Cerca Algoritm

in primo luogo prendere tutte le parole in ogni pahregraph e salvarli in un oggetto vettoriale (come builed spiegato più avanti)

e confrontare relazione a interrogare Vector di ogni Pargraph vettore

su ogni parola usa lo Stemer Poter per renderlo cose a grappolo come bambino e bambini

var Vector = function(phar){ 

var self = this; 
self.InitVector = function(){ 
    var wordArray = self.spltwords(phar); 
    self.VectorSize = wordArray .length; 
    var stemdWordArray = self.runPotterStemmer(wordArray); 
    self.VectoData = self.GroupAndCountWords(stemdWordArray) ; 
} 
self.VectoData ={}; 

self.runPotterStemmer = function(arr){ 
//run potter as seen in link 
} 
self.spltwords= function(arr){ 
//run split 
} 
    self.GroupAndCountWords = function(arr) 
    { 
     for(var i=0;i<arr.length;i++) 
      { 
       if(VectoData[arr[i]] === undefine) 
       { 
        VectoData[arr[i]] = 0;  
       } 
       else{ 
        VectoData[arr[i]] = VectoData[arr[i]] +1;   
       } 

      } 
    } 
self.compare = function(queryVector){ 
    // compare  queryVector to current vector and return a simlarty number 
    // number of simeler words counr in query divided by the length of phargrafh      
}       
self.InitVector() 
return self; 
+0

stemmer in JS https://github.com/jedp/porter-stemmer – yamsalm

1

Disclaimer - I am a author.

Puoi anche provare ItemsJS. Questo è un motore di ricerca in JavaScript che supporta il testo completo, la sfaccettatura e l'ordinamento.

Qui di seguito troverete un esempio interattivo - ItemsJS + VueJS:

var configuration = { 
 
    searchableFields: ['title', 'tags', 'actors'], 
 
    sortings: { 
 
    name_asc: { 
 
     field: 'name', 
 
     order: 'asc' 
 
    } 
 
    }, 
 
    aggregations: { 
 
    tags: { 
 
     title: 'Tags', 
 
     size: 10 
 
    }, 
 
    actors: { 
 
     title: 'Actors', 
 
     size: 10 
 
    }, 
 
    genres: { 
 
     title: 'Genres', 
 
     size: 10 
 
    } 
 
    } 
 
} 
 

 
// the rows comes from external resources 
 
// https://github.com/itemsapi/itemsapi-example-data/blob/master/jsfiddle/imdb.js 
 
itemsjs = itemsjs(rows, configuration); 
 

 
var vm = new Vue({ 
 
    el: '#el', 
 
    data: function() { 
 

 
    // making it more generic 
 
    var filters = {}; 
 
    Object.keys(configuration.aggregations).map(function(v) { 
 
     filters[v] = []; 
 
    }) 
 

 
    return { 
 
     query: '', 
 
     // initializing filters with empty arrays 
 
     filters: filters, 
 
    } 
 
    }, 
 
    methods: { 
 
    reset: function() { 
 
     var filters = {}; 
 
     Object.keys(configuration.aggregations).map(function(v) { 
 
     filters[v] = []; 
 
     }) 
 

 
     this.filters = filters; 
 
     this.query = ''; 
 
    } 
 
    }, 
 
    computed: { 
 
    searchResult: function() { 
 

 
     var result = itemsjs.search({ 
 
     query: this.query, 
 
     filters: this.filters 
 
     }) 
 
     return result 
 
    } 
 
    } 
 
});
<script src="https://cdn.rawgit.com/itemsapi/itemsapi-example-data/master/jsfiddle/imdb.js"></script> 
 
<script src="https://cdn.rawgit.com/itemsapi/itemsjs/master/dist/itemsjs.js"></script> 
 
<script src="https://cdn.jsdelivr.net/vue/latest/vue.min.js"></script> 
 
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/> 
 
<div id="el"> 
 
    <nav class="navbar navbar-default navbar-fixed-top"> 
 
    <div class="container"> 
 
     <div class="navbar-header"> 
 
     <a class="navbar-brand" href="#" v-on:click="reset()">ItemsJS movies</a> 
 
     </div> 
 
     <div id="navbar"> 
 
     <form class="navbar-form navbar-left"> 
 
      <div class="form-group"> 
 
      <input type="text" v-model="query" class="form-control" placeholder="Search"> 
 
      </div> 
 
     </form> 
 
     </div><!--/.nav-collapse --> 
 
    </div> 
 
    </nav> 
 

 
    <div class="container" style="margin-top: 50px;"> 
 

 
    <h1>List of items ({{ searchResult.pagination.total }})</h1> 
 

 
    <p class="text-muted">Search performed in {{ searchResult.timings.search }} ms, facets in {{ searchResult.timings.facets }} ms</p> 
 

 
    <div class="row"> 
 
     <div class="col-md-2 col-xs-2"> 
 
     <div v-for="facet in searchResult.data.aggregations"> 
 
      <h5 style="margin-bottom: 5px;"><strong style="color: #337ab7;">{{ facet.title }}</strong></h5> 
 

 
      <ul class="browse-list list-unstyled long-list" style="margin-bottom: 0;"> 
 
      <li v-for="bucket in facet.buckets"> 
 
      <div class="checkbox block" style="margin-top: 0; margin-bottom: 0;"> 
 
       <label> 
 
       <!--<input class="checkbox" type="checkbox" v-on:click="updateFilters(facet.name, bucket.key)" v-model="filters[bucket.key]" value="{{ bucket.key }}" v-bind:value="isChecked2()">--> 
 
       <!--<input class="checkbox" type="checkbox" v-on:click="updateFilters(facet.name, bucket.key)" v-model="filters[bucket.key]" v-bind:value="bucket.key">--> 
 
       <input class="checkbox" type="checkbox" v-model="filters[facet.name]" v-bind:value="bucket.key"> 
 
       {{ bucket.key }} ({{ bucket.doc_count }}) 
 
       </label> 
 
      </div> 
 
      </li> 
 
      </ul> 
 
     </div> 
 
     </div> 
 

 
     <div class="col-md-10 col-xs-10"> 
 
     <div class="breadcrumbs"></div> 
 
     <div class="clearfix"></div> 
 
     <!--<h3>List of items ({{ searchResult.pagination.total }})</h3>--> 
 
     <table class="table table-striped"> 
 
      <tbody> 
 
      <tr v-for="item of searchResult.data.items"> 
 
      <td><img style="width: 100px;" v-bind:src="item.image"></td> 
 
      <td></td> 
 
      <td> 
 
       <b>{{ item.name }}</b> 
 
       <br /> 
 
       {{ item.description }} 
 
      </td> 
 
      <td></td> 
 
      <td> 
 
       <span style="font-size: 12px; display: block; float: left; background-color: #dbebf2; border-radius: 5px; padding: 1px 3px 1px 3px; margin: 2px;" v-for="tag in item.tags">{{ tag }}</span> 
 
      </td> 
 
      </tr> 
 
      </tbody> 
 
     </table> 
 
     <div class="clearfix"></div> 
 
     </div> 
 

 
     <div class="clearfix" style="margin-bottom: 100px;"></div> 
 
    </div> 
 
    </div> 
 
</div>

Problemi correlati