3

私はCakePHP(最新リリース)でタグ検索をコーディングしていますが、私が作成したソリューションは、CakePHPの他の部分がいかに簡単であるかに比べて複雑すぎるようです。うまくいけば、誰かが私を正しい方向に向けたり、現在の解決策を改善するのを手伝ってくれるでしょう。

私のアプリの各ユーザーは、php、objective-c、javascript、jqueryなどのタグで自分自身にタグを付けることができます。別のタイプのユーザーは、特定のタグを持つユーザーを検索できます。彼らは検索するかもしれません:php、objective-c、ios。一致するタグの数の順にユーザーの配列を返す必要があります。3つのタグすべてを持つユーザーが配列の上部に表示されます。

これがデータベースのサンプルと私のソリューションです。これを改善するための助けを本当に感謝します。

【データベース】

ここに画像の説明を入力してください

[解決]

                //Search Array
            //Format: array('objective-c', 'javascript', 'jquery', 'php')
            $tag_array = explode(",", $this->request->data["User"]["search"]);

            //Get Tag IDs - array([id] => [id])
            //Format: array([1] => '1', [2] => '2', [4] => '4', [15] => '15')
            $result_tag_ids = $this->User->TagsUser->Tag->find('list', array(
                'conditions' => array(
                    "Tag.name" => $tag_array
                ),
                'fields' => array('Tag.id')    
            ));

            //Get User IDs - array([id] => [id])
            //Format: array([24] => '24', [24] => '24', [26] => 26, [27] => '27')
            $result_user_ids = $this->User->TagsUser->find('list', array(
                'conditions' => array(
                    "TagsUser.tag_id" => $result_tag_ids
                ),
                'fields' => array('TagsUser.user_id')     
            ));


            //Remove Duplicate user ids and add a count of how many tags matched & sort the array in that order
            //Format:  array([26] => 1, [24] => 2, [27] => 3)
            $counted_user_ids = array_count_values($result_user_ids);
            asort($counted_user_ids);


            //Get the keys (user_ids)
            $list_user_ids = array_keys($counted_user_ids); 

            //Get these users in the order of the sorted array
            $search_result = $this->User->find('all', array(
                'conditions' => array(
                    "User.id" => $list_user_ids
                ),
                'order' => 'FIELD(User.id,' . implode(" ,", $list_user_ids) . ')'

            ));
4

1 に答える 1

2

これを試してみてください:

$tag_array = explode(",", $this->request->data["User"]["search"]);
//arrays expanded for better readability, 
//you should be able to compress in fewer lines if desired

$options = array();
$options['contain'] = ''; 
//or recursive=-1, depends of what you are using to avoid extra models/fields

$options['joins'][0]['table'] = 'tags_users';
$options['joins'][0]['conditions'] = 'User.id = user_id';
$options['joins'][1]['alias'] = 'Tag';
$options['joins'][1]['table'] = 'tags'; 
$options['joins'][1]['conditions']= 'Tag.id = tag_id';
$options['fields'] =  array('User.id', 'COUNT(*) as tag_counter');
$options['group']  =  'User.id';
$options['order']  =  'tag_counter DESC';
$options['conditions']['Tag.name'] = $tag_array;
$search_result = $this->User->find('all', $options);

print_r($search_result)与える必要があります:

    Array
    (
        [0] => Array
            (
                [User] => Array
                    (
                        [id] => (user id)
                    )
                [0] => Array
                    (
                        [tag_counter] => (how many tags)
                    )
            )
        [...]
    )

私はそれがあなたのために働くことを願っています。各ユーザーが同じクエリでどのタグを持っているかも知りたい場合は、containまたはrecursive値を調整するだけです。

于 2012-08-16T20:30:51.750 に答える