0

タグごとに関連商品を提案し、最も一致した順に並べ替えたい。

製品とタグの間の HABTM モデルの関連付け

class Product extends AppModel {
//..
var $hasAndBelongsToMany = array("Tag");
//..
}

タグモデルではその逆です。また、結合テーブル名は「products_tags」です。

サンプル用

//just sample of Product contain Tag data
$products[0]['Tag'] = array('touch', 'phone', '3G', 'apple'); //iPhone
$products[1]['Tag'] = array('phone', '3G', 'BB'); //BB
$products[2]['Tag'] = array('touch', '3G', 'apple'); //iPad
$products[3]['Tag'] = array('3G', 'air card'); //3G air card

このサンプルでは、​​優先順位による iPhone の並べ替えに最も関連するものは次のとおりです。

  1. ipad (3 タグで見つかりました)
  2. BB (2 つのタグで見つかりました)
  3. エアカード (一致するのは 1 つだけ)

Model find() を使用して、次のようなサブクエリを取得する Cake の方法:

SELECT DISTINCT (product_id) AS id, (
/* sub-query counting same tags*/
SELECT COUNT(*) FROM tags as Tag
LEFT JOIN products_tags AS ProductTag ON ( Tag.id = ProductTag.tag_id )
WHERE product_id = id
AND Tag.name IN ( 'touch', 'phone', '3G', 'apple' )

) AS priority /*this is weight count by how many same tags*/
FROM  `tags` as Tag
LEFT JOIN products_tags AS ProductTag ON ( Tag.id = ProductTag.tag_id )
WHERE Tag.name
IN ( 'touch', 'phone', '3G', 'apple' ) 
ORDER BY priority DESC

上記の SQL クエリは、必要なものを正確に返します。しかし、パラメータを CakePHP の AppModel->find() メソッドに解析する方法が見つかりません。

4

1 に答える 1

0

この SQL の結果がページネーションを使用しない場合 (通常の Web ページの関連製品が 3 ~ 5 エントリであると仮定)、代わりにこの複雑な SQL を使用しないのはなぜですか?

つまり、 Product モデルに関数 relatedProducts() を作成します

次に $this->query($sql) を使用します

サンプルコードは次のとおりです。

class Product extends AppModel {
  //..
  var $hasAndBelongsToMany = array("Tag");
  //..
  function relatedProducts($parameters){
    $sql = "select..... where ....$parameters...";
    return $this->query($sql);
  }
}

次に、コントローラーでそれを使用できます

$this->Product->relatedProducts($some_parameters);
于 2010-08-04T12:05:03.840 に答える