2012-08-06 14 views
16

¿Hay una biblioteca de JavaScript que pueda determinar si una cadena coincide con una consulta de búsqueda? Debe ser eficiente y proporcionar una funcionalidad de consulta avanzada como la de Google o LexisNexis (cosas como y/o operadores, sinónimos y paréntesis). Cualquier tipo de funciones de búsqueda avanzada sería genial; no tiene que ser una coincidencia exacta con ningún motor de búsqueda en particular.Biblioteca de JavaScript para buscar en el estilo del motor de búsqueda?

Motivación: Tengo una página HTML con un cuadro de búsqueda seguido de un grupo de párrafos (que tienen identificadores únicos y se generan a partir de una matriz de JavaScript). Cuando el usuario escribe una consulta de búsqueda en el cuadro y presiona intro, todos los párrafos deben estar ocultos (es decir, su display establecido en none) si no coinciden con la consulta.

Mi estrategia actual (usando jQuery):

  1. independiente la cadena de consulta en una serie de palabras clave mediante su división sobre los espacios en blanco.
  2. Ocultar todos los párrafos con $('p').hide().
  3. Para cada palabra clave, muestre un párrafo que lo contenga con $('p:contains("'+keyword+'")').show().

que es una función de búsqueda muy limitada que es sensible a mayúsculas, trata a todas las palabras clave como opcional, y no proporciona los operadores como and, or o paréntesis. También es ineficiente porque atraviesa cada cadena una vez para cada palabra clave, incluso si ya se ha hecho coincidir.

+0

para hacer mayúsculas y minúsculas, puede convertir la palabra clave en minúsculas y comprobar si coincide con i, e. keyword.toLowerCase() – Shreedhar

Respuesta

27

Aquí hay algunas bibliotecas que estoy evaluando para proyectos (en julio de 2013). Cualquiera de estos debe ser capaz de proporcionar el núcleo de la función de búsqueda.

Si usted se siente como la construcción de su propia, que aquí son implementaciones de 2 algoritmos derivados comunes para empezar:

En cuanto a la gestión de operadores de búsqueda de lógica booleana, tal vez this question about js query parsers sé útil.

+0

Gracias por compartir esto, me preguntaba si usted estaba de acuerdo y si tenía alguna solución mejorada para agregar en 2017. – Noitidart

+2

@Noitidart No he tenido necesidad de estos sistemas en un tiempo en lo que he estado trabajando, pero si tuviera que hacer algo hoy, mi primera opción seguiría siendo la misma que entonces: lunrjs – turtlemonvh

+0

Gracias @Turtlemonvh ¡Lo aprecio! – Noitidart

2

la mejor manera (fácil y bueno) es el uso de vectores de búsqueda Algoritm

primero tomar todas las palabras en cada pahregraph y guardarlos en un objeto vectorial (cómo builed explica más adelante)

y compara relación a la consulta del vector de cada pargraph vector

en cada palabra usar el Stemer Poter para que sea cosas de racimo como niño y niños

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 en JS https://github.com/jedp/porter-stemmer – yamsalm

1

Descargo de responsabilidad - Soy un autor.

También puedes probar ItemsJS. Este es un motor de búsqueda en JavaScript que admite texto completo, facetado y clasificación.

A continuación encontrará un ejemplo interactivo - 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>

2

que han trabajado en algunos proyectos de código abierto de JavaScript en la búsqueda y el espacio PNL. You could checkout search-index que parece estar cerca de lo que estás buscando.

Cuestiones relacionadas