Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
89 views
in Technique[技术] by (71.8m points)

javascript - How to change search function to accept any combination of words

When I try to search for the title of a product, it only shows results if it is either the exact words, one word, or a combination of consecutive words.

For example, if I'm trying to find the product blue flying car, the product does not show if I try searching for blue car. Basically I want my search to be fixed to accept different combinations. How can I do this?

  var item_xlsx = './assets/data/products.xlsx';
  var all_items = [];
  var all_cats = [];
  var subcats = [];
  var catQuery = '';
  var subCatQuery = '';
  var titleQuery = '';
  
  function load_data() {

    // get query parameters
    catQuery = get_param('cat');
    subCatQuery = get_param('subcat');
    titleQuery = get_param('searchtext');
    $('#searchtext').val(titleQuery);
    $('#cat').val(catQuery);
    
    fetch(item_xlsx).then(function (res) {
      if (!res.ok) throw new Error("fetch failed");
      return res.arrayBuffer();
    }).then(function (ab) {
      var data = new Uint8Array(ab);
      var workbook = XLSX.read(data, { type: "array" });
      var first_sheet_name = workbook.SheetNames[0];
      var worksheet = workbook.Sheets[first_sheet_name];
      all_items = XLSX.utils.sheet_to_json(worksheet, { raw: true });
      
      populate_cats();
      populate_subcats(catQuery);
      render_category_form();
      render_search_form(catQuery, titleQuery, all_items);
      render_search_summary(catQuery, titleQuery, all_items);
      render_search_results(catQuery, titleQuery, all_items);
    });
  }
  
   function get_param(name) {
    name = name.replace(/[[]/, '\[').replace(/[]]/, '\]');
    var regex = new RegExp('[\?&]' + name + '=([^&#]*)');
    var results = regex.exec(location.search);
    return results === null ? '' : decodeURIComponent(results[1].replace(/+/g, ' '));
  }

  /* Filter items and render search results */
   function render_search_results(cat, query, items) {

    let results = all_items.filter(function (value, index, self) { // filter by cat 
      if (!catQuery || catQuery === "") {
        return true;
      } else {
        return value.cat == catQuery;
      }
    }).filter(function (value, index, self) { // filter by subcat
      if (!subCatQuery || subCatQuery === "") {
        return true;
      } else {
        return value.subcat == subCatQuery;
      }
    }).filter(function (value, index, self) { // filter by query
      if (!titleQuery || titleQuery === "") {
        return true;
      } else {
        var regex = new RegExp(titleQuery, "i");
        return value.name.search(regex) != -1 || value.audience.search(regex) != -1;
      }
    })
question from:https://stackoverflow.com/questions/65894487/how-to-change-search-function-to-accept-any-combination-of-words

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try to filter for each word in search query - this way the results will only contain these items which contain all the words searched.

Searching function example for tests:

// setting the test array values
var all_items = ['abba the cure metall', 'abba the best songs', 'blue car abba', 'moose egipt sand sun abba', 'sunny day the company', 'abba songs', 'egiptian culture songs', 'blue sunny skies', 'singing songs when sky is blue', 'in a car with abba', 'in a car with moose', 'moose is blue', 'matallic moose', 'best songs while driving a car', 'metall skies of egipt', 'sing a song with abba'];

// converting the array into arr of objects similar to those in your code
$.each(all_items, function(i,v){
    all_items[i]= {name: v, audience: ''};
});

  
// display all elements
$.each(all_items, function(i,v){ $('#namesDiv').append( $('<div/>').text(v.name) ); });

//
$('form').submit(function(e){
  e.preventDefault();

  // setting the test query from input element
  var titleQuery = $('#search').val();

  // filter by query
  var queryParts = titleQuery.split(/[^w]+/g); // split the keywords
  var result_items = $.extend(true, [], all_items); // copy all items to result array
  for(var i=0; i<queryParts.length; i++){ // iterate through keywords
      var regex = new RegExp(queryParts[i], "i");
      // check if current keyword is a part of name if not remove the item from result array 
      result_items = result_items.filter(function (value, index, self) {
          return regex.test(value.name) || regex.test(value.audience);
      });
  }

  // show search results in console
  console.clear();
  console.info('found '+result_items.length+' items:');
  console.log(JSON.stringify(result_items));

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form><input id='search' value="song abba"><button type="submit">search</button></form>
<div id="namesDiv" style="padding-bottom:5em;"></div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...