【问题标题】:Javascript Search Engine AND clauseJavascript 搜索引擎 AND 子句
【发布时间】:2016-10-12 03:40:26
【问题描述】:

我正在使用 JS 和 jQuery 编写搜索引擎,而不是生成我的 PHP 数据库,但我在理解如何构造“查询”时遇到问题。

目前,填充对象数组的步骤如下。

1) PHP 后端开发一个 JSON 文件,其中包含特定数据库中的所有假期。

2) Javascript 前端提取此 JSON 并通过循环将其全部添加到数组中。

3) 用户有几个框,他们可以在其中搜索数组,并将所有结果添加到“结果”数组中,该数组每次都会相应更新。

我遇到的一个问题是;如何处理多个 if 子句? 例如,如果 search_time 和 search_state != "all",我需要将搜索范围缩小到仅包括满足 search_time AND search_state 值的对象。目前,查询是 OR 查询。

我来自 SQL 背景,所以像搜索一样接近 Javascript 对我来说有点不同,我们将不胜感激。

下面的Javascript搜索:

 for (var i=0; (i <= holidays.length) && (found < limit); i++) {
    var h = holidays[i];
    console.log(h);
    complete = false;
    while (!complete && (h != undefined)) {
        if (search_terms != "" && search_terms != undefined) {
            if (like(h.title, search_terms) || like(h.state, search_terms) || like(h.country, search_terms) || like(h.location, search_terms)) {
                results[found] = h;
                found += 1;
                complete = true;
            }
        }
        if (search_country != "all") {
            if (h.country != undefined) {
                if (like(h.country, "Australia") && !complete) {
                    results[found] = h;
                    found += 1;
                    complete = true;
                }
            }
        }
        if (search_state != "ALL") {
            if (like(h.state, search_state) && !complete) {
                results[found] = h;
                found += 1;
                complete = true;
            }
        }
        if (search_time != "all") {
            var cyear = new Date().getFullYear();
            var nyear = cyear + 1;
            if (search_time == 'n-year' && !complete) {
                if (h.startsyd != undefined) {
                    if (new Date(h.startsyd).getFullYear() >= nyear) {
                        results[found] = h;
                        found += 1;
                        complete = true;
                    }
                }
                else if (h.melbstart != undefined) {
                    if (new Date(h.melbstart).getFullYear() >= nyear) {
                        results[found] = h;
                        found += 1;
                        complete = true;
                    }
                }
            }
            else if (search_time == 'c-year' && !complete) {
                if (h.startsyd != undefined) {
                    if (new Date(h.startsyd).getFullYear() >= cyear && new Date(h.startsyd).getFullYear() < nyear) {
                        results[found] = h;
                        found += 1;
                        complete = true;
                    }
                }
                else if (h.melbstart != undefined) {
                    if (new Date(h.melbstart).getFullYear() >= cyear && new Date(h.melbend).getFullYear() < nyear) {
                        results[found] = h;
                        found += 1;
                        complete = true;
                    }
                }
            }
            else if (search_time == '6-months' && !complete) {
                var six = new Date().setMonth(this.getMonth() + 6);
                if (h.startsyd != undefined) {
                    if (new Date(h.startsyd <= six)) {
                        results[found] = h;
                        found += 1;
                        complete = true;
                    }
                }
                else if (h.melbstart != undefined) {
                    if (new Date(h.melbstart <= six)) {
                        results[found] = h;
                        found += 1;
                        complete = true;
                    }
                }
            }
            else if (search_time == '3-months' && !complete) {
                var three = new Date().setMonth(this.getMonth() + 3);
                if (h.startsyd != undefined) {
                    if (new Date(h.startsyd <= three)) {
                        results[found] = h;
                        found += 1;
                        complete = true;
                    }
                }
                else if (h.melbstart != undefined) {
                    if (new Date(h.melbstart <= three)) {
                        results[found] = h;
                        found += 1;
                        complete = true;
                    }
                }
            }
        }
        complete = true;
    }
}

【问题讨论】:

  • 哇,太棒了! +1但我喜欢事先找到这个问题的解决方案:)
  • “喜欢”有什么作用?
  • 比较两个字符串。如果它与其他字符串一样,则返回 true

标签: javascript jquery json search


【解决方案1】:

这种方式可以让你:

1) 添加更多字段比较(阅读标有数字 4.a 和 4.b 的项目,您可以添加 4.c、4.d 等,尽量保持清晰)。

2) 允许您选择 AND 或 OR 模式(带灵敏度)

3) 使用 jQuery 为您节省大量时间和代码。

4) 提供了strstr 函数,请阅读 cmets 的脚本部分。原始函数(链接)返回一个字符串,我通过返回 null 而不是“不匹配”字符串对其进行修改。

// 1. lets setup a database, you can pull it from PHP or some other else..
//
var holidays = [
   { title : "aaskjqkwqiuwqi" , state : "florida" },
  { title : "aaaaksjak222jski" , state : "california" },
  { title : "1281827888282" , state : "california" },
  { title : "aksjakjkas88112" , state : "florida" }
];

// 2. lets define some inputs
//
var i_find = "88";   // what to find
var i_state = "all";  // what to find

// 3. define some internal conditions.
//
var result_type = 'AND';  // set to: AND or OR
var at_least = 2; // when OR, at least N items to have a match..
var results = [];

// 4. for each holiday entries we will count how many conditions match,
//  and depending on the search modality (AND or OR) then we put results
//
$(holidays).each(function(index,obj){
    var matches = [];

    // 4.a find by title and say if it success or not
    matches.push({ res: strstr(obj.title, i_find) ? true : false });
    
    // 4.b find by state, and again, say if it success or not
    if("all" != i_state)
    matches.push({ res: strstr(obj.state, i_state) ? true : false });

    // 4.c more search attributes ? add them here
     

    // 5. process results
    // we will count how many questions (4a,4b..) success:
    var n_matches = 0;
    $(matches).each(function(i,o){ if(true == o.res) n_matches++; });

    // 5.b return results depending on the search model: AND or OR, 
    // 
    if(('AND' == result_type) && (n_matches == matches.length))
       results.push(obj);  
    if(('OR' == result_type) && (n_matches > at_least))
       results.push(obj);  
});

// 6. we have results, if 'results' has entries.
console.log('Search Type: '+result_type);
results.length ? console.log('WE HAVE A MATCH FOR:'
  +i_find+' please examine results array') 
     : console.log('NO MATCH');

if(results.length) console.log(results);
// 7. have a nice day. :)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script>
  /* taken from: https://stackoverflow.com/a/9123997/937815 */
  function strstr (haystack, needle) {
    var i = 0,
        tempLength = 0,
        temp = [];
    for (;;) {
        if (haystack[i] === undefined || needle == null) {
            return null;
        }
        //if the char doesn't match then reset
        else if (haystack[i] !== needle[tempLength]) {
            temp = [];
            tempLength = 0;
        } 
        //the char matches so let's store it.
        else if (haystack[i] === needle[tempLength]) {
            temp[tempLength] = haystack[i];
            if (needle[tempLength + 1] === undefined) {
                return temp;
            }
            tempLength++;
        }
     i++;
   }
};
</script>

【讨论】:

    猜你喜欢
    • 2011-09-21
    • 1970-01-01
    • 2012-02-02
    • 2014-04-29
    • 2011-01-21
    • 1970-01-01
    • 2014-02-18
    • 2011-01-05
    相关资源
    最近更新 更多