0

私は、可能なすべての引数やものなしで、WordPress の wp_list_pages よりも効率的な (より少ない db 呼び出しなど) 関数を一緒にハックしようとしています。wp_posts テーブルは次のようになります。

ID      post_title          post_parent
1       Skate brand no1     5
2       Skate brand no2     5
3       Products            0
4       Bikes               3
5       Skateboards         3
6       About               0
7       Contact             6
8       Surfboards          3

そして、次のような配列が必要です。

array
    1 => Products
        array
            1 => Bikes
            2 => Skateboards
                array
                    1 => Skate brand no1
                    2 => Skate brand no2
            3 => Surfboards
    2 => About
        array
            1 => Contact

このタスクにどのようにアプローチすればよいですか?

アップデート!

私のサイトのフロント ページにある約 4 ~ 5 個の wp_list_pages を @Gedrox が提供するコードに置き換えることで、1 日の平均応答時間が不安定な 780 ~ 1000 ミリ秒から安定した 595 ~ 625 ミリ秒に減少しました。すばらしい!

4

2 に答える 2

1

私が見る限り、あなたの例では、必要な数の子を持つことができると考えています。

このアプローチは、再帰を使用して達成する必要があります。実際、wordpress の構造上、ノードの数だけクエリを実行し、ノードに子があるかどうかを確認しないと、ツリー全体を取得することはできません。

nこれは、ノードごとに子を持つことができる樹枝状の構造です。現時点では、MySQL は再帰的なサブクエリをサポートしていないため、このテーブル ロジックでは、log(m)クエリを必要とせずに完全な「パス」を取得することはできません (平均的なケースで、mは考慮するツリーのノードの数です)。

これは見かけほど単純ではありません。1 つのクエリ内ですべてのツリーを取得し、その方法で SQL クエリを 1 つに最小化する方法はいくつかありますが、それにはデータ テーブルを変更する必要があります。

これは、例を含むより詳細なサイトです。ここでは、実行できるいくつかの代替案を確認できます。

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

編集: 繰り返します:これは、1つのmysqlクエリで再帰なしで取得できるものではありません。無限の子供の概念を誤解しないでください。@Gedrox の回答では、ツリーに3 つのレベルがある場合にのみ機能します。

于 2013-02-28T21:02:33.247 に答える
1

完全なサイトマップが必要な場合は、すべてのレコード (SELECT私が推測する 1 つ) を読み取り、PHP コードで階層を整理する必要があります。

サンプルコード:

// TODO: get this from DB
$list = array(
    array('ID' => 1, 'post_title' => 'Skate brand no1', 'post_parent' => 5),
    array('ID' => 2, 'post_title' => 'Skate brand no2', 'post_parent' => 5),
    array('ID' => 3, 'post_title' => 'Products', 'post_parent' => 0),
    array('ID' => 4, 'post_title' => 'Bikes', 'post_parent' => 3),
    array('ID' => 5, 'post_title' => 'Skateboards', 'post_parent' => 3),
    array('ID' => 6, 'post_title' => 'About', 'post_parent' => 0),
    array('ID' => 7, 'post_title' => 'Contact', 'post_parent' => 6),
    array('ID' => 8, 'post_title' => 'Surfboards', 'post_parent' => 3),
);

$rootPages = array();
$pagesById = array();

foreach ($list as $key => &$row) {
    if ($row['post_parent'] == 0) {
        $rootPages[] = &$row;
    }
}

foreach ($list as $key => &$row) {
    $pagesById[$row['ID']] = &$row;
}

foreach ($list as $key => &$row) {
    if ($row['post_parent'] != 0) {
        $pagesById[$row['post_parent']]['children'][] = &$row;
    }
}

print_r($rootPages);
于 2013-02-28T20:51:00.607 に答える