0

データベースの記事を再分類したいと考えています。特定の記事のテキストを展開し、カテゴリ テーブルに表示されている記事の 1 つの単語に一致するタグがあるかどうかを確認し、この記事をこのカテゴリ名で更新します。私のコードはここにあります。すべてのカテゴリの最大記事数が 5 になるように制限したいと思います。しかし、更新制限は機能しません。ありがとう。

<?php
header('Content-type:text/html; charset=utf-8');
$db = mysql_connect("localhost","root","root") or die("can not connect Mysql Server");
mysql_select_db("12",$db);
$result = mysql_query("SELECT title,content,id,cat,date FROM articles Order By date DESC"); //get all the articles
$count = 0;
$ids = array();
$categories = array('1','2','3','4','5','6','7','8','9','10');//category numbers, for 1 = art, 2 = travel... these are stored in another refrenced DB table
$curCategory = array_shift($categories);
echo $curCategory;
while ($row = mysql_fetch_array($result))
{
$tt = $row['title'].'&nbsp;'.$row['content'];
$tt = preg_replace('/[^a-zA-Z0-9 ]/','',$tt);
$words = preg_split("/\s+/",$tt);   
$uniqueWords = array_keys(array_flip($words)); // broken article sentence into words
$parts = '';
foreach($uniqueWords as $word){     
$parts[] = " tag1 = '$word' OR tag2 = '$word' OR tag3 = '$word' OR tag4 = '$word' OR tag5 = '$word' ";   
} 
$where = implode(" OR ", $parts);
mysql_select_db("12",$db);
mysql_query("SET NAMES utf8");
    $query1 = mysql_query("SELECT count(*) as count FROM tag1 WHERE ($where) AND category ='count($categories)' ");  //put the break words into reference table match out the category number
    $count = 0;
    while ($row = mysql_fetch_array($query1)) {
        $count = $row['count'];
    } 
    if($count) {
        $ids[] = $row['id'];
        $count++;
        if($count == 5) {
             mysql_query("UPDATE articles SET cat = '$curCategory' WHERE id in ('".implode("', '", $ids)."')"); //update every category max articles 
            if(!$curCategory = array_shift($categories)) {
                break;
            }
            $count = 0;
            $ids = array();
        }
    }
}
?>

参照表

category | tag1    | tag2   | tag3       | tag4    |  tag5  
1        | paint   | picture| sculpture  | photo   |  bronze   
2        | tourism | travel | tour       | journey |  trip
3        | style   | vogue  | fashion    | mode    |  Popular
... // 10 categories, category 1 = art , category 2 = travel ...
4

4 に答える 4

2

非常に奇妙なコードです。しかし... $ids[] = $row['id'];- SQLにはid列がないため、結果にIDはありません。おそらく$row、外側と内側の両方のサイクルで使用するためです-それが問題です。

また、100 個のユニークな単語 (あまり多くありませんよね?) を含む記事が 500 個の sql クエリを形成することをご存知ORですか? :)

そして、どうmysql_select_dbですかmysql_query("SET NAMES utf8");-なぜ彼らはサイクルにいるのですか、なぜですか?

于 2011-04-06T11:50:53.013 に答える
0

このコードを分析してみましょう:

// this query returns one row with column `count`, you're comparing column
// `category` to the literal string `count($categories)` where
// `$categories` is an array of numbers and therefore evaluates to `count(Array)`
$query1 = mysql_query("SELECT count(*) as count FROM tag1 WHERE ($where) AND category ='count($categories)' ");
$count = 0;
// warning: overwriting previous $row variable
while ($row = mysql_fetch_array($query1)) {
    // an if($row=...) is better since you've on row anyway
    // Contents of $row = array( 'count' => NUMBER );
    // You're overwriting $count with the number of found articles
    $count = $row['count'];
}
// unless the query failed or there are no articles found, the next condition is true
if($count) {
    // undeclared variable $ids; $row['id'] does not exist since it is overwritten
    $ids[] = $row['id'];
    // The next lines do not limit the number of updates, it only updates
    // if $count == 4; where $count is the number of articles in a category
    $count++;
    if($count == 5) {
         mysql_query("UPDATE articles SET cat = '$curCategory' WHERE id in ('".implode("', '", $ids)."')");
        // so if the current catgeory has five articles, quit?
        if(!$curCategory = array_shift($categories)) {
            break;
        }
        // otherwise, reset for the next category
        $count = 0;
        $ids = array();
    }
}

あなたは間違いなくあなたのコードを見て、あなたがすべてを理解しているかどうか見るべきです。$row上書きは意図されていないと確信しています。また、クエリも$query1正しくありません。変数に名前を付けるときは、よりわかりやすくします。たとえば$catCount_rowの代わりに使用します。毎回$row上書きしていることに注意してください。おそらく、ループからそれを取り除きたいと思うでしょう。$countwhile

記事数が4に達しない場合、更新は行われません。

于 2011-04-06T12:10:10.240 に答える
0

まず、達成しようとしていることの説明は、ほとんどの SO ユーザーの要件には理解できないと思います。したがって、質問に関連する完全な回答を得るには、質問をより詳細で構造的に書き直す必要があります。

現在のコードは非常に乱雑で、特定のタスクを達成しようとする間違った方法がいくつかあります。

私を襲ったいくつかの問題があり、ここにリストします。

  • マニュアルをチェックして、機能を正しく使用しているかどうかを確認しますか
  • 同じデータベースを 2 回選択します ( mysql_select_db('12',$db))。
  • カテゴリの静的配列を作成してから、最初の要素を削除しています..なぜですか?
  • array_keys(array_flip($words));代わりにあなたの使用array_unique
  • あなたはカウント変数を正しく使用していません。インクリメントしたいと思うときに上書きするだけです
    • これに使えますmysql_result('count',$query)
  • ID はデータベースのどこから来たのですか ( $ids[] = $row['id'];) << WTF

正直なところ、コードの残りの部分はめちゃくちゃで、私でさえ理解できません。ウェブからコードの一部をコピーして、指を交差させたようです。

また、報奨金として 50 ポイントを提供していることにも驚いています。

于 2011-04-06T12:22:03.603 に答える
0

怖い。

他の回答がよく説明しているように、コードは面倒ですが、タグデータの構造の選択も問題を引き起こします。

5 つのタグに対して 5 つの列ではなく、別のタグ テーブルを作成し、それを記事にリンクします。

article | tag       |
  1     | paint     |
  1     | picture   |
  1     | sculpture |
  1     | photo     |
  1     | bronze    |
  2     | tourism   |
  2     | travel    |
  2     | tour      |

その後、タグを付けるときに、タグが tag1 か tag2 か、tag3 が NULL かどうか、または気が変わって結局 6 つのタグが必要かどうかを心配する必要はありません。この構造は、クエリの「パーツ」ビットを次のようにすることで、0 から任意の数のタグに対して機能します。

$parts = " tag in ('"
        .implode($uniqueWords,"', '")
        ."')";
// e.g. if uniqueWords = ['one','two','three'], $parts= "tag in ('one','two','three','')"

その内破は、すべての引用符と括弧を適切な場所に配置するために、おそらく微調整が必​​要です。

ただし、実際の問題には答えません。記事の最初の 5 つのキーワード、任意の 5 つのタグ、または最適な 5 つのタグを見つけようとしているかどうかは、私にはわかりません。私はこのようなものを提案します。

あなたの記事を分解し、ユニークな単語を探すときは、「the」のような一般的な英語の単語を除いて、単語の出現回数を数えます. 次に、一意の単語を出現順に並べ替えます。最も繰り返しの多い単語が最初になります。記事の主な単語のリストがあります。最初の 5 つを取得すると、それらがタグになります。テーブルに挿入します。

または、面倒に聞こえるかもしれませんが、最終的にはより効率的なソリューションを次に示します。このプロセスを完全に MySQL で実行するデータベース プロシージャを記述します。次の 2 つのテーブルが必要です。

tagstable - 1 column "tag" is the PK
| paint     |
| picture   |    articlewordstable - 1 column "word" is the PK - empty     
| sculpture |    | -   | 
| photo     |    | -   |     
| bronze    |

トークン化された単語を articlewordstable に挿入します。次に、tagstable と結合するそのテーブルをクエリします。

SELECT word FROM articlewordstable
INNER JOIN tagstable
ON tag = word;

タグでもある単語のリストが表示されます。5 つの結果の制限を設定することもできます。

SELECT word, count(word) occurrences FROM articlewordstable
INNER JOIN tagstable
ON tag = word
GROUP BY word
ORDER BY occurrences DESC;

これにより、タグリストにも表示される最も使用されている単語が得られます. それも 5 つに制限することができ、その後は適切に使用してください。

お役に立てれば!

于 2011-04-12T20:09:55.447 に答える