2013-04-23 77 views
1

我想用SQLSRV Driver在PHP和MSSQL中创建搜索功能。PHP Person爆炸式搜索

我只在页面上有一个搜索输入字段。 我想在我的表中搜索名为“Persons”的人员和以下列:SSN,名字,姓氏

问题是一个人可能在Firstname列中有一个或多个middelname。

我还想搜索单个字符串,例如:只有名字或只有中间名或姓氏。

我该怎么做?我应该使用PHP中的爆炸函数吗?

+0

除非重新构建数据模型,否则最终搜索速度会非常慢,因为在某些时候您必须对整个数据集执行字符串操作。 – 2013-04-23 09:16:03

+0

这是为什么?另外,如果我使用爆炸来改变LIKE查询 – 2013-04-23 09:18:16

+0

你刚才说你的名字列可能包含“John Joe Jack James Joaquin”。如果你只想搜索中间名,你将不得不删除“约翰”。在所有行中。很明显,你可以做一个'LIKE'%James%'',然后检查哪些行不是该列中的第一个名字......但这也会很慢。 – 2013-04-23 09:21:23

回答

0

我建议建立一个搜索索引。

下面我假设你persons表看起来像这样:

| person_id | firstname | lastname | ssn | 

为了能够建立一个搜索索引,你需要一个person_searchindex表:

| person_id | search_term | 

你然后可以使用像这样的东西:(这只是第一个草图)

<?php 
function addTermToSearchIndex($person_id, $term) 
{ 
    performQuery("INSERT INTO person_searchindex (person_id, search_term) 
        VALUES (" . (int)$person_id . ", ". 
        "\"" . escapeForQuery($term) . "\");"); 
} 

function buildSearchIndexForPerson($person_id, $firstname, $lastname, $ssn) 
{ 
    $firstnames = explode(" ", $firstname); 
    foreach($firstnames => $name) 
    { 
     addTermToSearchIndex($person_id, $name); 
    } 

    $lastnames = explode(" ", $lastname); 
    foreach($lastnames => $name) 
    { 
     addTermToSearchIndex($person_id, $name); 
    } 

    addTermToSearchIndex("$ssn"); 
} 

function deleteSearchIndexForPerson($person_id) 
{ 
    performQuery("DELETE FROM person_searchindex WHERE person_id = " . (int)$person_id . ";"); 
} 

function rebuildSearchIndexForPerson($person_id, $firstname, $lastname, $ssn) 
{ 
    deleteSearchIndexForPerson($person_id); 
    buildSearchIndexForPerson($person_id, $firstname, $lastname, $ssn); 
} 

function rebuildSearchIndex() 
{ 
    performQuery("DELETE FROM person_searchindex;"); 
    $result = performQuery("SELECT * FROM persons;"); 
    while($row = getRow($result)) 
    { 
     buildSearchIndexForPerson($ow["person_id"], $row["firstname"], $row["lastname"], $row["ssn"]); 
    } 
} 

function search($searchterm) 
{ 
    $sqlcond = "FALSE"; 

    $terms = explode(" ", $searchterm); 
    foreach($terms => $term) 
    { 
     $sqlcond .= " OR s.search_term LIKE \"%" . escapeForQuery($term) . "%\""; 
    } 

    return performQuery("SELECT p.person_id, p.firstname, p.lastname, p.ssn FROM persons AS p LEFT JOIN person_searchindex AS s ON p.person_id = s.person_id WHERE $sqlcond;"); 
} 

?> 

每当添加或更改人员行时,都会调用方法rebuildSearchIndexForPerson()。无论何时删除人员行,都可以拨打方法deleteSearchIndexForPerson()。您第一次想要搜索某些内容时,您必须致电rebuildSearchIndex()为您的老人行创建搜索索引。之后,您将可以使用search()功能。

正如我所说,这只是第一个草图。例如,您必须将方法performQueryescapeForQuerygetRow更改为您实际使用的内容。另外,php代码的质量并不是特别好。但它的工作原理应该清楚。