首页 > 解决方案 > 如何更改搜索功能以接受任何单词组合

问题描述

当我尝试搜索产品的标题时,它只会显示确切的单词、一个单词或连续单词的组合的结果。

例如,如果我正在尝试查找产品,如果我尝试搜索,blue flying car产品不会blue car显示。基本上我希望我的搜索被修复以接受不同的组合。我怎样才能做到这一点?

  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;
      }
    })

标签: javascripthtml

解决方案


尝试过滤搜索查询中的每个单词 - 这样结果将仅包含这些包含所有搜索单词的项目。

测试的搜索功能示例:

// 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>

嵌套在您的函数中时,上面的搜索代码将如下所示:

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

    var 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;
      }
    });

    if (titleQuery) { // filter by query
      var queryParts = titleQuery.split(/[^\w]+/g); // split the keywords from query
      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 or audience if not remove the item from results array 
        results = results.filter(function (value, index, self) {
            return regex.test(value.name) || regex.test(value.audience);
        });
      }
    }

如果您只需要搜索整个单词 - 只需使用正则表达式 - 上述解决方案包括子字符串匹配。


推荐阅读