Php 从数据源中搜索关键字并忽略关键字

Php 从数据源中搜索关键字并忽略关键字,php,mysql,Php,Mysql,我需要将数据库中的产品与来自数据源的产品进行匹配 datafeed有一个product name列 而我的数据库表有关键字和忽略关键字列 匹配应该是这样的:如果db IGNORE_关键字的ALLdb关键字与datafeed产品名称匹配,而db IGNORE_关键字的NONE与datafeed产品名称匹配,则为正匹配 例如 Datafeed: ID, Name, Url, ... 1, iPhone 5s 64GB Unlocked 1 year warranty, http://.... 2,

我需要将数据库中的产品与来自数据源的产品进行匹配

datafeed有一个product name列

而我的数据库表有关键字和忽略关键字列

匹配应该是这样的:如果db IGNORE_关键字的ALLdb关键字与datafeed产品名称匹配,而db IGNORE_关键字的NONE与datafeed产品名称匹配,则为正匹配

例如

Datafeed:

ID, Name, Url, ...
1, iPhone 5s 64GB Unlocked 1 year warranty, http://....
2, iPhone 5s 64GB Locked O2 2 years Deal, http://....

Database:
ID, KEYWORDS, IGNORE_KEYWORDS, ...
1000, iPhone 5s 64GB, Locked, ...
1001, iPhone 5s 64GB, Unlocked, ...
现在当我匹配时,它应该匹配:

Datafeed #1 to Database #1000
Datafeed #2 to Database #1001
问题是,使用直接查询很难匹配datafeed产品名称中数据库列中的所有关键字。我认为这根本不可能!但可能有一些直接的方法可以做到这一点

如果不是直接的方法,那么会有间接的方法吗?是否创建另一个表来保存数据库原始表的关键字和ID

进行此类匹配的最快和最优化的方法是什么?


提前谢谢

通过使用以下方法,我终于能够做到这一点:

我创建了两个新表:

product_keywords
id | keyword | tot_kwds

product_ignore_keyword
id | keyword
  • 首先,我从搜索源字符串中提取单词

  • 接下来,我使用此查询获取匹配的记录:

从product_keywords中选择id,tot_kwds,其中关键字在('word1','word2','word3')组中,按id计数(*)=tot_kwds

  • 通过这种方式,我获得了在搜索源字符串中包含所有关键字的ID。让我们将它们命名为
    关键字查找ID

  • 接下来,我将获得在忽略关键字映射中找到的ID:

从product\u ignore\u中选择id,其中id在(关键字找到id)中,关键字在('word1','word2','word3')

  • 现在我得到了在关键字中找到的ID,但也在忽略关键字中找到,比如说
    ignore keyword found id

  • 所以我的最终结果是:

找到的关键字ID-忽略找到的关键字ID

  • 我从最终结果中获取第一个id,这就是我们正在寻找的匹配产品
这个方法对我很管用

以下是php代码示例:

$arrW = getWordsFromString($searchString);

if ( !is_array($arrW) || count($arrW) == 0 )
    return 0;

$pids = array();
$sql = "select id, tot_kwds from product_keywords where keyword in ('".implode("', '", $arrW)."') group by id having count(*) = tot_kwds";
$res = db_query($sql);
while ( ($row = db_row($res)) )
    $pids[] = (int)$row['id'];

if ( count($pids) == 0 )
    return 0;

$nids = array();
$sql = "select id from product_ignore_keywords where id in (".implode(', ', $pids).") and keyword in ('".implode("', '", $arrW)."')";
$res = db_query($sql);
while ( ($row = db_row($res)) )
    $nids[] = (int)$row['id'];

$pids = array_diff($pids, $nids);

if ( count($pids) == 0 )
    return 0;

$finalId = (int)$pids[0];
我将等待任何建议,以进一步优化这个答案。如果没有,那么我将把它标记为接受答案


干杯

我终于能够通过以下方法做到这一点:

我创建了两个新表:

product_keywords
id | keyword | tot_kwds

product_ignore_keyword
id | keyword
  • 首先,我从搜索源字符串中提取单词

  • 接下来,我使用此查询获取匹配的记录:

从product_keywords中选择id,tot_kwds,其中关键字在('word1','word2','word3')组中,按id计数(*)=tot_kwds

  • 通过这种方式,我获得了在搜索源字符串中包含所有关键字的ID。让我们将它们命名为
    关键字查找ID

  • 接下来,我将获得在忽略关键字映射中找到的ID:

从product\u ignore\u中选择id,其中id在(关键字找到id)中,关键字在('word1','word2','word3')

  • 现在我得到了在关键字中找到的ID,但也在忽略关键字中找到,比如说
    ignore keyword found id

  • 所以我的最终结果是:

找到的关键字ID-忽略找到的关键字ID

  • 我从最终结果中获取第一个id,这就是我们正在寻找的匹配产品
这个方法对我很管用

以下是php代码示例:

$arrW = getWordsFromString($searchString);

if ( !is_array($arrW) || count($arrW) == 0 )
    return 0;

$pids = array();
$sql = "select id, tot_kwds from product_keywords where keyword in ('".implode("', '", $arrW)."') group by id having count(*) = tot_kwds";
$res = db_query($sql);
while ( ($row = db_row($res)) )
    $pids[] = (int)$row['id'];

if ( count($pids) == 0 )
    return 0;

$nids = array();
$sql = "select id from product_ignore_keywords where id in (".implode(', ', $pids).") and keyword in ('".implode("', '", $arrW)."')";
$res = db_query($sql);
while ( ($row = db_row($res)) )
    $nids[] = (int)$row['id'];

$pids = array_diff($pids, $nids);

if ( count($pids) == 0 )
    return 0;

$finalId = (int)$pids[0];
我将等待任何建议,以进一步优化这个答案。如果没有,那么我将把它标记为接受答案


干杯

唯一的方法是将关键字移动到单独的表中,每行一个关键字。然后就可以对它们执行查询了。一个查询是不可能的,但至少是可能的。谢谢您的回复。这里重要的是,特定产品的所有关键字都与单个datafeed产品名称匹配。因此,如果例如
iPhone-1000
5s-1000
匹配,但
64GB-1000
不匹配,则表示产品ID
1000
不匹配。我们如何做到这一点?我想这种匹配将需要一个独特的检查和一个having count(*)测试来验证产品的所有关键字是否匹配???有什么简单的方法吗?
从my_关键字WHERE value IN('iPhone-1000'、'5s-1000'、'64GB-1000')中选择COUNT(*)
然后检查计数是否为3。我想应该是这样的:
选择COUNT(*),id FROM my_关键字WHERE key IN('iPhone'、'5s'、'64GB')GROUP BY id
。所以这将返回所有带有计数的产品ID,我们选择那些匹配所有3个的,对吗?我想如果我们的关键字和搜索词都是唯一的,那么这就行了。唯一的方法是将关键字移动到一个单独的表中,每行一个关键字。然后就可以对它们执行查询了。一个查询是不可能的,但至少是可能的。谢谢您的回复。这里重要的是,特定产品的所有关键字都与单个datafeed产品名称匹配。因此,如果例如
iPhone-1000
5s-1000
匹配,但
64GB-1000
不匹配,则表示产品ID
1000
不匹配。我们如何做到这一点?我想这种匹配将需要一个独特的检查和一个having count(*)测试来验证产品的所有关键字是否匹配???有什么简单的方法吗?
从my_关键字WHERE value IN('iPhone-1000'、'5s-1000'、'64GB-1000')中选择COUNT(*)
然后检查计数是否为3。我想应该是这样的:
选择COUNT(*),id FROM my_关键字WHERE key IN('iPhone'、'5s'、'64GB')GROUP BY id
。因此,这将返回所有带有cou的产品ID