トップ 新規 編集 差分 一覧 ソース プレゼンテーション 検索 ヘルプ PDF RSS ログイン

Luceneの応用

Luceneの応用

  • Luceneへのデータの登録と検索
    • データの登録はAmazonから検索したデータを登録する形にしているが、手入力したデータを登録するフォームを作ればすぐに登録できる。

 Amazonからの検索ページ

  • searchFromAmazon.jsp
    • Amazon Web Serviceを用いて文献を検索する。検索された結果について必要に応じてLuceneへの登録ページへ入力できるようにしている。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml"%>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<!-- 設定? -->
<c:set var="amazonId">itasancentral-22</c:set><!-- ここではとりあえずのものを使っているが別のものを使うこと -->
<c:set var="devToken">D2MJGTR0QXUW0Z</c:set><!-- ここではとりあえずのものを使っているが別のものを使うこと -->
<fmt:requestEncoding value="utf-8" />
<!-- パラメータとして登録したい文献が渡されれば登録ページへ飛ぶ -->
<c:if test="${(empty param.search)&&(empty param.display)&&(!empty param.regist)}">
    <jsp:forward page="registFormFromAmazon.jsp" />
</c:if>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Amazonからの検索</title>
    <style>
        table,th,td{
            border-color:black;
            border-width:1px;
            border-style:solid;
        }
    </style>
</head>
<body style="text-align: center;">
<form action="${pageScope.request.requestURI}" method="post">
    <h3>Amazonからの検索</h3>
    検索キーワード:
    <input type="text" name="keyword" value="${param.keyword}"/>
    <input type="submit" name="search" value="検索"/>
    <c:if test="${!empty param.keyword}">
        <!-- Amazonからの検索処理 -->
        <c:url var="amazonUrl" value="http://xml.amazon.co.jp/onca/xml3">
            <c:param name="t" value="${amazonId}"/>
            <c:param name="dev-t" value="${devToken}"/>    
            <c:param name="mode" value="books-jp"/>    
            <c:param name="locale" value="jp"/>    
            <c:param name="type" value="heavy"/>
            <c:param name="f" value="xml"/>
            <c:param name="KeywordSearch" value="${param.keyword}"/>
            <c:set var="sort" value="+daterank" />
            <c:if test="${!empty param.sort}">
                <c:set var="sort" value="${param.sort}"/>
            </c:if>
            <c:param name="sort" value="${sort}"/>    
            <c:if test="${!empty param.page}">
                <c:param name="page" value="${param.page}"/>    
            </c:if>
        </c:url>
        <c:import var="amazonDoc" url="${amazonUrl}" />
        <x:parse var="amazonXml" doc="${amazonDoc}" />
        <hr>
        <!-- 検索結果の概要 -->
        検索キーワード「${param.keyword}」で<x:out select="$amazonXml/ProductInfo/TotalResults" />件検索しました。
        <c:set var="totalPage">
            <x:out select="$amazonXml/ProductInfo/TotalPages" />
        </c:set>
        <br />
        <!-- 並び替え変更 -->
        並び順:
        <select name="sort">
            <option value="+salesrank" ${(sort eq '+salesrank')?'selected':'' }>売れている順</option>
            <option value="+pricerank" ${(sort eq '+pricerank')?'selected':'' }>価格の安い順</option>
            <option value="+inverse-pricerank" ${(sort eq '+inverse-pricerank')?'selected':'' }>価格の高い順</option>
            <option value="+daterank" ${(sort eq '+daterank')?'selected':'' }>新しい順</option>
            <option value="-daterank" ${(sort eq '-daterank')?'selected':'' }>古い順</option>
            <option value="+titlerank" ${(sort eq '+titlerank')?'selected':'' }>書名順(昇順)</option>
            <option value="-titlerank" ${(sort eq '-titlerank')?'selected':'' }>書名順(降順)</option>
        </select>
        <!-- ページ移動 -->
        表示ページ
        <select name="page">
            <c:forEach begin="1" end="${totalPage}" var="i">
                <option value="${i}" ${(i eq param.page)?'selected':''}>${i}</option>
            </c:forEach>
        </select>
        /${totalPage}ページへ
        <input type="submit" name="display" value="再表示"/>
        <br />
        <br />
        <!-- 検索結果の表示 -->
        <table>
            <tr>
                <th>チェック</th>
                <th>画像</th>
                <th>著者</th><th>書名</th><th>出版社</th><th>出版年月日</th><th>ISBN</th><th>価格</th><th>ランキング</th>
            </tr>
            <x:forEach select="$amazonXml/ProductInfo/Details">
                <tr>
                    <td><input type="checkbox" name="isbn" value="<x:out select="Asin" />"></td>
                    <td><a href="<x:out select="@url" />"><img src="<x:out select="ImageUrlSmall" />" /></a></td>
                    <c:set var="author"><x:out select="Authors" /></c:set>
                    <c:set var="author">${fn:trim(author)}</c:set>
                    <td>${author}</td>
                    <input type="hidden" name="author<x:out select="Asin" />" value="${author}"/>
                    <td><x:out select="ProductName" /></td>
                    <input type="hidden" name="title<x:out select="Asin" />" value="<x:out select="ProductName" />"/>
                    <td><x:out select="Manufacturer" /></td>
                    <input type="hidden" name="publisher<x:out select="Asin" />" value="<x:out select="Manufacturer" />"/>
                    <td><x:out select="ReleaseDate" /></td>
                    <input type="hidden" name="date<x:out select="Asin" />" value="<x:out select="ReleaseDate" />"/>
                    <td><x:out select="Isbn" /></td>
                    <td nowrap="nowrap">
                        L:<x:out select="ListPrice" /><br/>
                        A:<x:out select="OurPrice" /><br/>
                        U:<x:out select="UsedPrice" />
                    </td>
                    <td><x:out select="SalesRank" /></td>
                </tr>
            </x:forEach>
        </table>
        <input type="submit" name="regist" value="チェックした文献を登録"/>
    </c:if>
</form>
</body>
</html>

 Amazonからの検索したデータのLuceneへの登録フォーム

  • registFormFromAmazon.jsp
    • アマゾンから検索したデータをとりあえず登録フォームに入力し、必要に応じて修正できるようにしている。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<fmt:requestEncoding value="utf-8" />
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Amazonからのデータを登録</title>
</head>
<body style="text-align:center">
    <h3>Amazonから取得したデータをLuceneに登録</h3>
    <form action="registToLucene.jsp" method="post">
    <c:forEach items="${paramValues['isbn']}" var="asin" varStatus="status">
        ISBN:<input type="text" name="isbn${status.count}" value="${asin}">
        <c:set var="author">author${asin}</c:set>
        著者名:<input type="text" name="author${status.count}" value="${param[author]}">
        <c:set var="title">title${asin}</c:set>
        書名:<input type="text" name="title${status.count}" value="${param[title]}">
        <c:set var="publisher">publisher${asin}</c:set>
        出版社:<input type="text" name="publisher${status.count}" value="${param[publisher]}">
        <c:set var="date">date${asin}</c:set>
        出版年月日:<input type="text" name="date${status.count}" value="${param[date]}">
        <br />
        <c:if test="${status.last}">
            <input type="hidden" name="dataSize" value="${status.count}">
        </c:if>
    </c:forEach>
    <input type="submit" value="Luceneに登録" />
    </form>
</body>
</html>

 投稿されたデータのLuceneへの登録ページ

  • registToLucene.jsp
    • 投稿されたデータをLuceneに登録するページ。著者名(author)、書名(title)などのフィールドをパラメータで渡せば、Amazonからのデータでなくても、登録ができる
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@page import="org.apache.lucene.index.IndexWriter"%>
<%@page import="org.apache.lucene.analysis.cjk.CJKAnalyzer"%>
<%@page import="org.apache.lucene.document.Document"%>
<%@page import="org.apache.lucene.document.Field"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<fmt:requestEncoding value="utf-8" />
<%!
    IndexWriter indexWriter;
    String dataDir;
    public void jspInit(){
        dataDir = getServletContext().getRealPath("/WEB-INF/index");
        try {
            indexWriter = new IndexWriter(dataDir,new CJKAnalyzer(),true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void jspDestroy(){
        try {
            indexWriter.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }
%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Luceneへの登録</title>
</head>
<body>
<%
    String dataSize = request.getParameter("dataSize");
    int size = Integer.parseInt(dataSize);
    for(int i=0;i<size;i++) {
        Document doc = new Document();
        //各フィールドに登録
        doc.add(new Field("isbn", request.getParameter("isbn"+(i+1)),Field.Store.YES,Field.Index.UN_TOKENIZED));
        doc.add(new Field("author", request.getParameter("author"+(i+1)),Field.Store.YES,Field.Index.UN_TOKENIZED));
        doc.add(new Field("title", request.getParameter("title"+(i+1)),Field.Store.YES,Field.Index.TOKENIZED));
        doc.add(new Field("publisher", request.getParameter("publisher"+(i+1)),Field.Store.YES,Field.Index.UN_TOKENIZED));
        doc.add(new Field("date", request.getParameter("date"+(i+1)),Field.Store.YES,Field.Index.UN_TOKENIZED));
        //キーワードフィールドとして他のデータも登録
        doc.add(new Field("keyword", request.getParameter("isbn"+(i+1)),Field.Store.NO,Field.Index.TOKENIZED));
        doc.add(new Field("keyword", request.getParameter("author"+(i+1)),Field.Store.NO,Field.Index.TOKENIZED));
        doc.add(new Field("keyword", request.getParameter("title"+(i+1)),Field.Store.NO,Field.Index.TOKENIZED));
        doc.add(new Field("keyword", request.getParameter("publisher"+(i+1)),Field.Store.NO,Field.Index.TOKENIZED));
        doc.add(new Field("keyword", request.getParameter("date"+(i+1)),Field.Store.NO,Field.Index.TOKENIZED));
        indexWriter.addDocument(doc);
        out.println(doc.getField("isbn").stringValue()+" - "+doc.getField("title").stringValue()+"が登録されました<br />");
    }
    indexWriter.flush();
%>
    <a href="searchLucene.jsp">検索ページへ</a>
</body>
</html>

 Luceneの検索

  • searchLucene.jsp
    • Luceneに登録されたデータから検索するフォームとその検索結果の表示を行う。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@page import="org.apache.lucene.search.IndexSearcher"%>
<%@page import="org.apache.lucene.search.Hits"%>
<%@page import="org.apache.lucene.search.Query"%>
<%@page import="org.apache.lucene.index.IndexReader"%>
<%@page import="org.apache.lucene.queryParser.QueryParser"%>
<%@page import="org.apache.lucene.analysis.cjk.CJKAnalyzer"%>
<%@page import="org.apache.lucene.document.Document"%>
<%@page import="org.apache.lucene.search.TermQuery"%>
<%@page import="org.apache.lucene.index.Term"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<fmt:requestEncoding value="utf-8" />
<%!
    IndexSearcher indexSearcher;
    String dataDir;
    public void jspInit(){
        dataDir = getServletContext().getRealPath("/WEB-INF/index");
        try {
            indexSearcher = new IndexSearcher(IndexReader.open(dataDir));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void jspDestroy(){
        try {
            indexSearcher.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }
%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Luceneからの検索</title>
</head>
<body>
    <h3>Luceneからの検索</h3>
    <form action="${pageContext.request.requestURI}" method="post">
        検索式:
        <input type="text" name="query" value="${param.query}">
        <!-- フィールドに何もなければkeywordで初期化 -->
        <c:set var="field">keyword</c:set>
        <c:if test="${!empty param.field}">
            <c:set var="field">${param.field}</c:set>
        </c:if>
        <select name="field">
            <option value="keyword" ${(field eq 'keyword')?'selected':''}>キーワード</option>
            <option value="author" ${(field eq 'author')?'selected':''}>著者名</option>
            <option value="title" ${(field eq 'title')?'selected':''}>書名</option>
            <option value="publisher" ${(field eq 'publisher')?'selected':''}>出版社</option>
            <option value="date" ${(field eq 'date')?'selected':''}>出版年</option>
            <option value="isbn" ${(field eq 'isbn')?'selected':''}>ISBN</option>
        </select>
        <input type="submit" value="検索">
    </form>
    <c:if test="${!empty param.query}">
    <%
        Query query = null;
        if(request.getParameter("field").equals("keyword")||request.getParameter("field").equals("title")) {
            QueryParser qparser = new QueryParser(request.getParameter("field"), new CJKAnalyzer());
            query = qparser.parse(request.getParameter("query"));
        } else {
            query = new TermQuery(new Term(request.getParameter("field"),request.getParameter("query")));
        }
        Hits hits = indexSearcher.search(query);
        out.println(request.getParameter("field")+"フィールドに対して検索語「"+request.getParameter("query")+"」で検索したところ"+hits.length() + "件の文献がヒットしました。<br/><br/>");
        for (int i = 0; i<hits.length() ; i++) {
            Document doc = hits.doc(i);
            out.println("著者名:"+doc.get("author")+",タイトル:"+doc.get("title"));
            out.println("出版社:"+doc.get("publisher"));
            out.println("<br/>");
        }
    %>
    </c:if>
</body>
</html>
registFormFromAmazon.jsp registToLucene.jsp searchFromAmazon.jsp searchLucene.jsp

最終更新時間:2007年12月08日 11時03分59秒