使用复选框进行多类别过滤

x6yk4ghg  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(345)

我对数据库是完全陌生的,但当时我正在尝试使用复选框实现具有多个类别的过滤器。假设我有一个包含3个表的数据库:games、attributes和values。在这里,我尝试实现一些eav db模型:

CREATE TABLE IF NOT EXISTS `games` (
 `id` int(255) NOT NULL,
 `game_name` varchar(50) NOT NULL,
  KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `games` (`id`, `game_name`) VALUES
(1, 'Grand Theft Auto Vice City'),
(2, 'Counter Strike 1.6'),
(3, 'Fallout 2'),
(4, 'Minecraft');

CREATE TABLE IF NOT EXISTS `attributes` (
  `attr_id` int(50) NOT NULL,
  `attribute_name` varchar(255) NOT NULL,
  KEY (`attr_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `attributes` (`attr_id`, `attribute_name`) VALUES
(1, 'release'),
(2, 'developer'),
(3, 'country');

CREATE TABLE IF NOT EXISTS `values` (
  `entity_id` int(255) NOT NULL,
  `attribute_id` int(50) NOT NULL,
  `value` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `values` (`entity_id`, `attribute_id`, `value`) VALUES
(1, 1, '2002'),
(1, 2, 'Rockstar'),
(1, 3, 'USA'),
(2, 1, '2000'),
(2, 2, 'Valve'),
(2, 3, 'USA'),
(3, 1, '1998'),
(3, 2, 'Black Isle Studios'),
(3, 3, 'USA'),
(4, 1, '2011'),
(4, 2, 'Mojang'),
(4, 3, 'Sweden');

ALTER TABLE `values`
  ADD CONSTRAINT `values_ibfk_1` FOREIGN KEY (`attribute_id`) REFERENCES `attributes` (`attr_id`),
  ADD CONSTRAINT `values_ibfk_2` FOREIGN KEY (`entity_id`) REFERENCES `games` (`id`);

my index.html有一些带有复选框的过滤器和三类过滤:发布日期、开发人员和开发国家:

<form id="filter">
 <h2>Date of release:</h2>
  <input type="checkbox" id="1998" name="1988"><label for="1988">1988</label><br>
<input type="checkbox" id="2000" name="2000"><label for="2000">2000</label><br>
<input type="checkbox" id="2002" name="2002"><label for="2002">2002</label><br>
<input type="checkbox" id="2011" name="2011"><label for="2011">2011</label>

<h2>Developer:</h2>
  <input type="checkbox" id="rockstar" name="Rockstar"><label for="rockstar">Rockstar</label><br>
<input type="checkbox" id="valve" name="Valve"><label for="valve">Valve</label><br>
<input type="checkbox" id="black-isle-studios" name="Black Isle Studios"><label for="black-isle-studios">Black Isle Studios</label><br>
<input type="checkbox" id="mojang" name="Mojang"><label for="mojang">Mojang</label>

<h2>Country:</h2>
  <input type="checkbox" id="usa" name="USA"><label for="usa">USA</label><br>
<input type="checkbox" id="sweden" name="Sweden"><label for="sweden">Sweden</label><br>
</form>

下面是我用来从客户端编译数据并用ajax查询发送数据的一些js:

var $checkboxes = $("input:checkbox");
$checkboxes.on("change", function(){
  var opts = getGamesFilterOptions();
  updateGames(opts);
});

function getGamesFilterOptions(){
  var opts = [];
  $checkboxes.each(function(){
    if(this.checked){
      opts.push(this.name);
    }
  });
  return opts;
}

function updateGames(opts){
 $.ajax({
  type: "POST",
  url: "submit.php",
  dataType : 'json',
  cache: false,
  data: {filterOpts: opts},
  success: function(records){
    //show games depending on which values have been checked//
    }
 });
}

我也试着写 submit.php 它将根据选中的属性过滤和返回游戏。现在它返回一个空数组。这里是主要的问题,我不太确定它应该如何正常工作

<?php 
$pdo = new PDO('mysql:host=localhost;dbname=games_db', 'root', '');
$opts = $_POST['filterOpts'];
$qMarks = str_repeat('?,', count($opts) - 1) . '?';

$statement = $pdo->prepare('SELECT games.game_name FROM games INNER JOIN values ON attribute_id = attributes.attr_id WHERE value IN ($qMarks)');
$statement->execute($opts);
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$json = json_encode($results);
echo($json);
?>
yv5phkfx

yv5phkfx1#

所以最后我想出了一个解决办法。所以这里是 games.sql 文件:

CREATE TABLE `attributes` (
  `attribute_id` int(255) UNSIGNED NOT NULL,
  `attribute_name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `attributes` (`attribute_id`, `attribute_name`) VALUES
(1, 'release'),
(2, 'developer'),
(3, 'country');

CREATE TABLE `games` (
  `game_id` int(255) UNSIGNED NOT NULL,
  `game_name` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `games` (`game_id`, `game_name`) VALUES
(1, 'Grand Theft Auto Vice City'),
(2, 'Counter Strike 1.6'),
(3, 'Fallout 2'),
(4, 'Minecraft');

CREATE TABLE `games_values` (
  `game_id` int(255) UNSIGNED NOT NULL,
  `attribute_id` int(255) UNSIGNED NOT NULL,
  `value` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `games_values` (`game_id`, `attribute_id`, `value`) VALUES
(1, 1, '2002'),
(1, 2, 'Rockstar'),
(1, 3, 'USA'),
(2, 1, '2000'),
(2, 2, 'Valve'),
(2, 3, 'USA'),
(3, 1, '1998'),
(3, 2, 'Black Isle Studios'),
(3, 3, 'USA'),
(4, 1, '2011'),
(4, 2, 'Mojang'),
(4, 3, 'Sweden');

ALTER TABLE `games_values`
  ADD CONSTRAINT `games_values_ibfk_1` FOREIGN KEY (`attribute_id`) REFERENCES `attributes` (`attribute_id`),
  ADD CONSTRAINT `games_values_ibfk_2` FOREIGN KEY (`game_id`) REFERENCES `games` (`game_id`);

以及 submit.php :

<?php 
$pdo = new PDO('mysql:host=localhost;dbname=games', 'root', '');
$opts = $_GET['filterOpts'];
$qMarks = str_repeat('?,', count($opts) - 1) . '?';

$statement = $pdo->prepare("SELECT DISTINCT games.game_name FROM games INNER JOIN games_values ON games.game_id = games_values.game_id WHERE value IN ($qMarks)");
$statement->execute($opts);
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$json = json_encode($results);
echo($json);
?>

本主题讨论了多复选框过滤器这一问题的总体思路。
如果这种方法足够有效的话,很高兴听到有经验的开发人员的意见。谢谢。

相关问题