質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • Java

    14145questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • MySQL

    6036questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • SQL

    2485questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ngramを用いて全文検索をおこなっているのですが、重複した検索結果が出てしまいます。

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 986

Sfidante

score 90

データベースに「新宿駅」というデータで「Aさん」が格納されている場合、
『新宿駅』で検索をかけると、
”新宿”で検索した時に引っかかり、
”宿駅”で検索した時にも引っかかり、
結果として、「Aさん」が2回抽出されてしまいます。

該当するコードは下記になります。
//例えば新宿駅というパラメータを取得したとします。
String place = request.getParameter("新宿駅");
//NgramクラスのcreateNgramメソッドで処理します
                    Map<String, Integer> map = Ngram.createNgram(place, 2);
//2文字以内は処理されないので、mapにplaceの文字列をそのまま格納します。
                    if(map.size() == 0){
                        map.put(place , 1);
                    }
//ここで、繰り返し処理をおこなって検索結果をsetAttributeしてJSPで表示させようとしています。
                    for (Map.Entry<String, Integer> entry : map.entrySet()) {
                        String place_piece = entry.getKey();
                        tomorrowEngineer.addAll(tomorrowlunchdao.searchTomorrowLunchEngineerList(userid, today, tomorrow, place_piece, duration));
                    }


//Ngramクラス
public final static Map<String, Integer> createNgram(final String text, final int n) {
        final String[] words = text.split("", 0);
        final int numberOfNgram = words.length - n; // 生成されるn-gramの数(ループ回数になる)
        Map<String, Integer> ngramMap = new HashMap<String, Integer>();
        StringBuilder ngramSb = new StringBuilder();
 
        // ngramとその出現回数を格納したMapを生成
        for (int i = 0; i < numberOfNgram; ++i) {
            // ngramを1つ生成
            for (int j = i; j < i + n; ++j) {
                int k = j + 1;
                ngramSb.append(words[j]).append(words[k]).delete(2, 3);
            }
            ngramSb.deleteCharAt(ngramSb.length() - 1);
            String ngramStr = ngramSb.toString();
            ngramSb.delete(0, ngramSb.length());
 
            // 生成したngramをMapに入れてカウント
            if (ngramMap.containsKey(ngramStr)) {
                ngramMap.put(ngramStr, ngramMap.get(ngramStr) + 1);
            } else {
                ngramMap.put(text.substring(text.length()-2) , 1);
                ngramMap.put(ngramStr, 1);
            }
        }
        ngramSb.append(text.substring(text.length()-2));
        return ngramMap;
    }

//DAOでのtomorrowlunchdao.searchTomorrowLunchEngineerListメソッド
public List<TomorrowLunchEngineerBeans> searchTomorrowLunchEngineerList(int userid , Timestamp today , Timestamp tomorrow , String place_piece , int duration)throws Exception{
            LinkedList<TomorrowLunchEngineerBeans> ll = new LinkedList<TomorrowLunchEngineerBeans>();
            String sql = "SELECT userid , engineer_id , (SELECT place FROM tomorrow_lunch_place WHERE word_id = userid)AS place , "
                    + "duration , date , name , photo , age , years_of_experience , "
                    + "projectmanager , projectleader , engineer , programer , director , coder , designer , tester , introduction "
                    + "FROM (SELECT * FROM tomorrow_lunch WHERE date >= ?)AS time "
                    + "JOIN account_user AS au USING(userid) "
                    + "JOIN entry_engineer AS ee USING(userid) "
                    + "JOIN profile_engineer AS pe USING(engineer_id) "
                    + "WHERE date < ? "
                    + "AND duration = ? "
                    + "AND userid IN (SELECT word_id FROM tomorrow_lunch_place WHERE MATCH(ngram) AGAINST(? IN BOOLEAN MODE))"
                    + "AND au.userid NOT IN (SELECT offer_send_userid FROM offer WHERE offer_rec_userid = ?) "
                    + "AND au.userid NOT IN (SELECT offer_rec_userid FROM offer WHERE offer_send_userid = ?) "
                    + "AND au.userid NOT IN (SELECT userid1 FROM room WHERE userid2 = ?) "
                    + "AND au.userid NOT IN (SELECT userid2 FROM room WHERE userid1 = ?) "
                    + "AND userid <> ?";
            PreparedStatement ps = connect.prepareStatement(sql);
            ps.setTimestamp(1, today);
            ps.setTimestamp(2, tomorrow);
            ps.setInt(3, duration);
            ps.setString(4, place_piece);
            ps.setInt(5, userid);
            ps.setInt(6, userid);
            ps.setInt(7, userid);
            ps.setInt(8, userid);
            ps.setInt(9, userid);
            ResultSet rs = ps.executeQuery();
            while(rs.next()){
                TomorrowLunchEngineerBeans beans = new TomorrowLunchEngineerBeans();
                beans.setUserid(rs.getInt("userid"));
                beans.setEngineerid(rs.getInt("engineer_id"));
                beans.setPlace(rs.getString("place"));
                beans.setDuration(rs.getInt("duration"));
                beans.setDate(rs.getTimestamp("date"));
                beans.setName(rs.getString("name"));
                beans.setPhoto(rs.getString("photo"));
                beans.setAge(rs.getInt("age"));
                beans.setYears_of_experience(rs.getInt("years_of_experience"));
                beans.setProjectmanager(rs.getBoolean("projectmanager"));
                beans.setProjectleader(rs.getBoolean("projectleader"));
                beans.setEngineer(rs.getBoolean("engineer"));
                beans.setProgramer(rs.getBoolean("programer"));
                beans.setDirector(rs.getBoolean("director"));
                beans.setCoder(rs.getBoolean("coder"));
                beans.setDesigner(rs.getBoolean("designer"));
                beans.setTester(rs.getBoolean("tester"));
                beans.setIntroduction(rs.getString("introduction"));
                ll.add(beans);
            }
            return ll;
        }

とても長くなってすみません。。。
どこを変更すべきかご教授いただけると幸いです。
何卒よろしくお願い致します。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

ごめんなさい、コード自体は詳しく見てないのですが、NGRAMで検索する時は、
SELECT * FROM table WHERE MATCH(target) AGAINST('+"新宿 宿駅"' IN BOOLEAN MODE);
となるようなクエリを1回発行するのが正しいです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/11 17:54

    ご返信が遅くなり申し訳ございません。
    terushu様のおかげで
    重複無く取り出すことが出来ます。
    ありがとうございました。

    キャンセル

関連した質問

同じタグがついた質問を見る

  • Java

    14145questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • MySQL

    6036questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • SQL

    2485questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。