<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>4.6. タグ検索・参照関係の逆引き — groonga v3.0.5 documentation</title> <link rel="stylesheet" href="../_static/groonga.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../', VERSION: '3.0.5', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/underscore.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <link rel="shortcut icon" href="../_static/favicon.ico"/> <link rel="top" title="groonga v3.0.5 documentation" href="../index.html" /> <link rel="up" title="4. Tutorial" href="../tutorial.html" /> <link rel="next" title="4.7. match_columnsパラメータ" href="match_columns.html" /> <link rel="prev" title="4.5. ドリルダウン" href="drilldown.html" /> </head> <body> <div class="header"> <h1 class="title"> <a id="top-link" href="../index.html"> <span class="project">groonga</span> <span class="separator">-</span> <span class="description">An open-source fulltext search engine and column store.</span> </a> </h1> <div class="other-language-links"> <ul> <li><a href="../../../ja/html/tutorial/index.html"><img src="../_static/jp.png" alt="日本語">日本語版はこちら</a></li> </ul> </div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="match_columns.html" title="4.7. match_columnsパラメータ" accesskey="N">next</a> |</li> <li class="right" > <a href="drilldown.html" title="4.5. ドリルダウン" accesskey="P">previous</a> |</li> <li><a href="../index.html">groonga v3.0.5 documentation</a> »</li> <li><a href="../tutorial.html" accesskey="U">4. Tutorial</a> »</li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="id1"> <h1>4.6. タグ検索・参照関係の逆引き<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h1> <p>本チュートリアルで、groongaはカラム値として他のテーブルへの参照の配列を持つことができることを紹介いたしました。実は、テーブルへの参照の配列データを用いることによって、いわゆるタグ検索を行うことが可能となります。</p> <p>タグ検索はgroongaの転置インデックスというデータ構造を用いて高速に行われます。</p> <div class="section" id="id2"> <h2>4.6.1. タグ検索<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h2> <p>動画共有サイトの検索エンジンを作ることを想定します。1つの動画には、その動画の特徴を表す、複数の語句が付与されています。「ある語句が付与されている動画の一覧を取得する」検索を行いたいとします。</p> <p>実際に、動画情報のテーブルを作成し、検索をしてみましょう。</p> <p>動画の情報を保存する、Videoテーブルを作成します。Videoテーブルでは、動画のタイトルをtitleカラムに、動画のタグ情報をtagsカラムにTagテーブル型で複数格納しています。 タグの情報を保存する、Tagテーブルを作成します。Tagテーブルでは、タグ文字列を主キーに格納し、Videoテーブルのtagsカラムに対するインデックスをindex_tagsカラムに格納しています。</p> <p>Execution example:</p> <div class="highlight-none"><div class="highlight"><pre>table_create --name Video --flags TABLE_HASH_KEY --key_type UInt32 # [[0, 1337566253.89858, 0.000355720520019531], true] table_create --name Tag --flags TABLE_HASH_KEY --key_type ShortText # [[0, 1337566253.89858, 0.000355720520019531], true] column_create --table Video --name title --flags COLUMN_SCALAR --type ShortText # [[0, 1337566253.89858, 0.000355720520019531], true] column_create --table Video --name tags --flags COLUMN_VECTOR --type Tag # [[0, 1337566253.89858, 0.000355720520019531], true] column_create --table Tag --name index_tags --flags COLUMN_INDEX --type Video --source tags # [[0, 1337566253.89858, 0.000355720520019531], true] load --table Video [ {"_key":1,"title":"Soccer 2010","tags":["Sports","Soccer"]}, {"_key":2,"title":"Zenigata Kinjirou","tags":["Variety","Money"]}, {"_key":3,"title":"groonga Demo","tags":["IT","Server","groonga"]}, {"_key":4,"title":"Moero!! Ultra Baseball","tags":["Sports","Baseball"]}, {"_key":5,"title":"Hex Gone!","tags":["Variety","Quiz"]}, {"_key":6,"title":"Pikonyan 1","tags":["Animation","Pikonyan"]}, {"_key":7,"title":"Draw 8 Month","tags":["Animation","Raccoon"]}, {"_key":8,"title":"K.O.","tags":["Animation","Music"]} ] # [[0, 1337566253.89858, 0.000355720520019531], 8] </pre></div> </div> <p>インデックスカラムを作成すると、全文検索が高速に行えるようになります。インデックスカラムは、対象のカラムに保存されたデータに更新があったとき、自動的に更新されます。</p> <p>「ある語句が付与されている動画の一覧を取得する」検索を行いましょう。</p> <p>Execution example:</p> <div class="highlight-none"><div class="highlight"><pre>select --table Video --query tags:@Variety --output_columns _key,title # [ # [ # 0, # 1337566253.89858, # 0.000355720520019531 # ], # [ # [ # [ # 2 # ], # [ # [ # "_key", # "UInt32" # ], # [ # "title", # "ShortText" # ] # ], # [ # 2, # "Zenigata Kinjirou" # ], # [ # 5, # "Hex Gone!" # ] # ] # ] # ] select --table Video --query tags:@Sports --output_columns _key,title # [ # [ # 0, # 1337566253.89858, # 0.000355720520019531 # ], # [ # [ # [ # 2 # ], # [ # [ # "_key", # "UInt32" # ], # [ # "title", # "ShortText" # ] # ], # [ # 1, # "Soccer 2010" # ], # [ # 4, # "Moero!! Ultra Baseball" # ] # ] # ] # ] select --table Video --query tags:@Animation --output_columns _key,title # [ # [ # 0, # 1337566253.89858, # 0.000355720520019531 # ], # [ # [ # [ # 3 # ], # [ # [ # "_key", # "UInt32" # ], # [ # "title", # "ShortText" # ] # ], # [ # 6, # "Pikonyan 1" # ], # [ # 7, # "Draw 8 Month" # ], # [ # 8, # "K.O." # ] # ] # ] # ] </pre></div> </div> <p>このように、「Variety」、「Sports」、「Animation」のようなタグで検索を行うことができました。</p> </div> <div class="section" id="id3"> <h2>4.6.2. 参照関係の逆引き<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h2> <p>groongaはテーブル間の参照関係の逆引きを高速に行うためのインデックスを付与することができます。タグ検索は、その1例にすぎません。</p> <p>例えば、ソーシャルネットワーキングサイトにおける友人関係を逆引き検索することができます。</p> <p>以下の例では、ユーザー情報を格納するUserテーブルを作成し、ユーザー名を格納するusernameカラム、ユーザーの友人一覧を配列で格納するfriendsカラムとそのインデックスのindex_friendsカラムを追加しています。</p> <p>Execution example:</p> <div class="highlight-none"><div class="highlight"><pre>table_create --name User --flags TABLE_HASH_KEY --key_type ShortText # [[0, 1337566253.89858, 0.000355720520019531], true] column_create --table User --name username --flags COLUMN_SCALAR --type ShortText # [[0, 1337566253.89858, 0.000355720520019531], true] column_create --table User --name friends --flags COLUMN_VECTOR --type User # [[0, 1337566253.89858, 0.000355720520019531], true] column_create --table User --name index_friends --flags COLUMN_INDEX --type User --source friends # [[0, 1337566253.89858, 0.000355720520019531], true] load --table User [ {"_key":"ken","username":"健作","friends":["taro","jiro","tomo","moritapo"]} {"_key":"moritapo","username":"森田","friends":["ken","tomo"]} {"_key":"taro","username":"ぐるんが太郎","friends":["jiro","tomo"]} {"_key":"jiro","username":"ぐるんが次郎","friends":["taro","tomo"]} {"_key":"tomo","username":"トモちゃん","friends":["ken","hana"]} {"_key":"hana","username":"花子","friends":["ken","taro","jiro","moritapo","tomo"]} ] # [[0, 1337566253.89858, 0.000355720520019531], 6] </pre></div> </div> <p>指定したユーザーを友人リストに入れているユーザーの一覧を表示してみましょう。</p> <p>Execution example:</p> <div class="highlight-none"><div class="highlight"><pre>select --table User --query friends:@tomo --output_columns _key,username # [ # [ # 0, # 1337566253.89858, # 0.000355720520019531 # ], # [ # [ # [ # 5 # ], # [ # [ # "_key", # "ShortText" # ], # [ # "username", # "ShortText" # ] # ], # [ # "ken", # "健作" # ], # [ # "taro", # "ぐるんが太郎" # ], # [ # "jiro", # "ぐるんが次郎" # ], # [ # "moritapo", # "森田" # ], # [ # "hana", # "花子" # ] # ] # ] # ] select --table User --query friends:@jiro --output_columns _key,username # [ # [ # 0, # 1337566253.89858, # 0.000355720520019531 # ], # [ # [ # [ # 3 # ], # [ # [ # "_key", # "ShortText" # ], # [ # "username", # "ShortText" # ] # ], # [ # "ken", # "健作" # ], # [ # "taro", # "ぐるんが太郎" # ], # [ # "hana", # "花子" # ] # ] # ] # ] </pre></div> </div> <p>さらに、ドリルダウンを使って、友人リストに入っている数の一覧を表示してみましょう。</p> <p>Execution example:</p> <div class="highlight-none"><div class="highlight"><pre>select --table User --limit 0 --drilldown friends # [ # [ # 0, # 1337566253.89858, # 0.000355720520019531 # ], # [ # [ # [ # 6 # ], # [ # [ # "_id", # "UInt32" # ], # [ # "_key", # "ShortText" # ], # [ # "friends", # "User" # ], # [ # "index_friends", # "User" # ], # [ # "username", # "ShortText" # ] # ] # ], # [ # [ # 6 # ], # [ # [ # "_key", # "ShortText" # ], # [ # "_nsubrecs", # "Int32" # ] # ], # [ # "taro", # 3 # ], # [ # "jiro", # 3 # ], # [ # "tomo", # 5 # ], # [ # "moritapo", # 2 # ], # [ # "ken", # 3 # ], # [ # "hana", # 1 # ] # ] # ] # ] </pre></div> </div> <p>このように、テーブルの参照関係を逆にたどる検索ができました。</p> </div> <div class="section" id="id4"> <h2>4.6.3. インデックス付きジオサーチ<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h2> <p>位置情報のカラムに対して、インデックスを付与することが出来ます。大量の位置情報レコードを検索する場合に、検索速度が速くなります。</p> <p>Execution example:</p> <div class="highlight-none"><div class="highlight"><pre>table_create --name GeoIndex --flags TABLE_PAT_KEY --key_type WGS84GeoPoint # [[0, 1337566253.89858, 0.000355720520019531], true] column_create --table GeoIndex --name index_point --type Site --flags COLUMN_INDEX --source location # [[0, 1337566253.89858, 0.000355720520019531], true] load --table Site [ {"_key":"http://example.org/","location":"128452975x503157902"}, {"_key":"http://example.net/","location":"128487316x502920929"} ] # [[0, 1337566253.89858, 0.000355720520019531], 2] select --table Site --filter 'geo_in_circle(location, "128515259x503187188", 5000)' --output_columns _key,location # [ # [ # 0, # 1337566253.89858, # 0.000355720520019531 # ], # [ # [ # [ # 1 # ], # [ # [ # "_key", # "ShortText" # ], # [ # "location", # "WGS84GeoPoint" # ] # ], # [ # "http://example.org/", # "128452975x503157902" # ] # ] # ] # ] </pre></div> </div> <p>同様に、位置情報レコードを用いてソートする場合に、ソート速度が速くなります。</p> <p>Execution example:</p> <div class="highlight-none"><div class="highlight"><pre>select --table Site --filter 'geo_in_circle(location, "128515259x503187188", 50000)' --output_columns _key,location,_score --sortby '-geo_distance(location, "128515259x503187188")' --scorer '_score = geo_distance(location, "128515259x503187188")' # [ # [ # 0, # 1337566253.89858, # 0.000355720520019531 # ], # [ # [ # [ # 2 # ], # [ # [ # "_key", # "ShortText" # ], # [ # "location", # "WGS84GeoPoint" # ], # [ # "_score", # "Int32" # ] # ], # [ # "http://example.org/", # "128452975x503157902", # 2054 # ], # [ # "http://example.net/", # "128487316x502920929", # 6720 # ] # ] # ] # ] </pre></div> </div> </div> </div> </div> </div> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../index.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">4.6. タグ検索・参照関係の逆引き</a><ul> <li><a class="reference internal" href="#id2">4.6.1. タグ検索</a></li> <li><a class="reference internal" href="#id3">4.6.2. 参照関係の逆引き</a></li> <li><a class="reference internal" href="#id4">4.6.3. インデックス付きジオサーチ</a></li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="drilldown.html" title="previous chapter">4.5. ドリルダウン</a></p> <h4>Next topic</h4> <p class="topless"><a href="match_columns.html" title="next chapter">4.7. match_columnsパラメータ</a></p> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../_sources/tutorial/index.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="match_columns.html" title="4.7. match_columnsパラメータ" >next</a> |</li> <li class="right" > <a href="drilldown.html" title="4.5. ドリルダウン" >previous</a> |</li> <li><a href="../index.html">groonga v3.0.5 documentation</a> »</li> <li><a href="../tutorial.html" >4. Tutorial</a> »</li> </ul> </div> <div class="footer"> © Copyright 2009-2013, Brazil, Inc. </div> </body> </html>