{"title":"検索","version":"6.1","locale":"ja","docname":"topics/db/search","url":"/ja/6.1/topics/db/search/","canonical":"https://djangodocs.dev/ja/6.1/topics/db/search/","summary":"ウェブアプリケーションの一般的なタスクは、ユーザーからの入力を用いてデータベース内のデータを検索することです。簡単なケースなら、オブジェクトのリストをカテゴリごとにフィルタリングすることで実現できるかもしれません。しかし、もっと複雑なユースケースでは、重み付き検索、カテゴリー分け、ハイライト、複数言語対応などが必要になることもあ…","html":"<h1>検索<a class=\"heading-anchor\" href=\"#search\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>ウェブアプリケーションの一般的なタスクは、ユーザーからの入力を用いてデータベース内のデータを検索することです。簡単なケースなら、オブジェクトのリストをカテゴリごとにフィルタリングすることで実現できるかもしれません。しかし、もっと複雑なユースケースでは、重み付き検索、カテゴリー分け、ハイライト、複数言語対応などが必要になることもあります。このドキュメントでは、そのようなユースケースについて説明するとともに、利用できるツールを紹介します。</p>\n<p>ここでは <a class=\"reference internal\" href=\"/ja/6.1/topics/db/queries/\"><span class=\"doc\">クエリを作成する</span></a> で使われたのと同じモデルを使って説明します。</p>\n<section id=\"use-cases\">\n<h2>ユースケース<a class=\"heading-anchor\" href=\"#use-cases\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"standard-textual-queries\">\n<h3>標準的なテキストのクエリ<a class=\"heading-anchor\" href=\"#standard-textual-queries\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Text-based fields have a selection of matching operations. For example, you may\nwish to allow the lookup of an author like so:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__contains</span><span class=\"o\">=</span><span class=\"s2\">&quot;Terry&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Author: Terry Gilliam&gt;, &lt;Author: Terry Jones&gt;]</span>\n</code></pre></div>\n<p>これは非常に弱い解決方法です。なぜなら、ユーザーが著者名の正確な部分文字列を知っている必要があるからです。case-insensitive なマッチ (<a class=\"reference internal\" href=\"/ja/6.1/ref/models/querysets/#std-fieldlookup-icontains\"><code class=\"xref std std-lookup docutils literal notranslate\"><span class=\"pre\">icontains</span></code></a>) を利用すれば少しはましになりますが、ほとんど違いはありません。</p>\n</section>\n<section id=\"a-database-s-more-advanced-comparison-functions\">\n<h3>データベースが持つ高度な比較関数<a class=\"heading-anchor\" href=\"#a-database-s-more-advanced-comparison-functions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>PostgreSQL を使っている場合、 Django は <a class=\"reference internal\" href=\"/ja/6.1/ref/contrib/postgres/search/\"><span class=\"doc\">データベース固有のツールの選択肢</span></a> があり、より複雑なクエリオプションが利用できます。他のデータベースでは、プラグインやユーザ定義関数を使うことで、様々なツ ールを選択できます。Django は今のところ、そのようなツールをサポートしていません。PostgreSQL の例をいくつか使って、データベースがどのような機能を持っているかを説明します。</p>\n<aside class=\"admonition-searching-in-other-databases admonition\">\n<p class=\"admonition-title\">他のデータベースにおける検索</p>\n<p><a class=\"reference internal\" href=\"/ja/6.1/ref/contrib/postgres/#module-django.contrib.postgres\" title=\"django.contrib.postgres: PostgreSQL-specific fields and features\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.postgres</span></code></a> が提供するすべての検索ツールは、 <a class=\"reference internal\" href=\"/ja/6.1/ref/models/lookups/\"><span class=\"doc\">カスタムルックアップ</span></a> や <a class=\"reference internal\" href=\"/ja/6.1/ref/models/database-functions/\"><span class=\"doc\">データベース関数</span></a> のようなパブリック API を利用して構築されています。データベースによっては、同様のAPIを許可するクエリを構築できるはずです。この方法で実現できない特定のことがあれば、チケットをオープンしてください。</p>\n</aside>\n<p>上記の例では、大文字と小文字を区別しないルックアップがの方が使いやすいでしょう。英語以外の名前を扱う場合、さらなる改善は <a class=\"reference internal\" href=\"/ja/6.1/ref/contrib/postgres/lookups/#std-fieldlookup-unaccent\"><code class=\"xref std std-lookup docutils literal notranslate\"><span class=\"pre\">アクセントなし比較</span></code></a> を使うことです:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__unaccent__icontains</span><span class=\"o\">=</span><span class=\"s2\">&quot;Helen&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Author: Helen Mirren&gt;, &lt;Author: Helena Bonham Carter&gt;, &lt;Author: Hélène Joy&gt;]</span>\n</code></pre></div>\n<p>これには別の問題があります。異なる綴りの名前とマッチする場合です。 <code class=\"docutils literal notranslate\"><span class=\"pre\">Helen</span></code> を検索すると <code class=\"docutils literal notranslate\"><span class=\"pre\">Helena</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">Hélène</span></code> がヒットしますが、その逆はヒットしません。もう一つの方法は <a class=\"reference internal\" href=\"/ja/6.1/ref/contrib/postgres/lookups/#std-fieldlookup-trigram_similar\"><code class=\"xref std std-lookup docutils literal notranslate\"><span class=\"pre\">trigram_similar</span></code></a> 比較を使うことです。</p>\n<p>例えば次のようにします:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__unaccent__lower__trigram_similar</span><span class=\"o\">=</span><span class=\"s2\">&quot;Hélène&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Author: Helen Mirren&gt;, &lt;Author: Hélène Joy&gt;]</span>\n</code></pre></div>\n<p>今度は別の問題です。&quot;Helena Bonham Carter &quot;という長い名前は、もっと長いので表示されません。trigram 検索では、3文字のすべての組み合わせを考慮し、検索文字列とソース文字列の両方で何回現れるかを比較します。より長い名前では、ソース文字列に現れない組み合わせが多くなるため、近接一致とは見なされなくなります。</p>\n<p>ここでの比較関数の正しい選択は、使用されている言語や検索されるテキストのタイプなど、データセットによって異なります。これまで見てきた例はすべて、ユーザーがソースデータに近いものを（さまざまな定義で）入力する可能性が高い短い文字列に関するものです。</p>\n</section>\n<section id=\"document-based-search\">\n<h3>文書ベースの検索<a class=\"heading-anchor\" href=\"#document-based-search\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>標準的なデータベース操作は、大きなテキストブロックを考慮し始めると、有用なアプローチではなくなります。上記の例は文字列に対する操作と考えることができますが、全文検索は実際の単語を調べます。使用するシステムにもよりますが、以下のような考え方が使われるでしょう:</p>\n<ul class=\"simple\">\n<li><p>&quot;a&quot;, &quot;the&quot;, &quot;and &quot;などの &quot;ストップワード&quot; は無視する。</p></li>\n<li><p>&quot;pony&quot; と &quot;ponies&quot; が似ているとみなされるように、単語のステミング（Stemming）を行う。</p></li>\n<li><p>テキスト内での出現頻度や、タイトルやキーワードのようなフィールドの重要性に基づいて単語に重みを付けるなど、異なる基準に基づいて単語を重み付けする。</p></li>\n</ul>\n<p>検索ソフトウェアを使用するための代替手段は数多くありますが、その中でも最も有名なものに <a class=\"reference external\" href=\"https://www.elastic.co/\">Elastic</a> と <a class=\"reference external\" href=\"https://solr.apache.org/\">Solr</a> があります。これらは完全なドキュメントベースの検索ソリューションです。Django モデルからのデータでこれらを使うには、データベース ID への後方参照を含め、データをテキスト文書に変換するレイヤが必要です。このエンジンを使って検索すると、特定の文書が返され、それをデータベースで調べることができます。このプロセスを支援するために設計された、さまざまなサードパーティライブラリがあります。</p>\n<section id=\"postgresql-support\">\n<h4>PostgreSQL のサポート<a class=\"heading-anchor\" href=\"#postgresql-support\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>PostgreSQLには独自の全文検索実装が組み込まれています。他の検索エンジンほど強力ではありませんが、データベース内にあるため、カテゴリ分類などの他のリレーショナルクエリと簡単に組み合わせることができるという利点があります。</p>\n<p><a class=\"reference internal\" href=\"/ja/6.1/ref/contrib/postgres/#module-django.contrib.postgres\" title=\"django.contrib.postgres: PostgreSQL-specific fields and features\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.postgres</span></code></a> モジュールは、これらのクエリを作成するためのヘルパーをいくつか提供しています。例えば、&quot;cheese&quot; に言及している全てのブログエントリを選択するクエリがあります:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">body_text__search</span><span class=\"o\">=</span><span class=\"s2\">&quot;cheese&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[&lt;Entry: Cheese on Toast recipes&gt;, &lt;Entry: Pizza recipes&gt;]</span>\n</code></pre></div>\n<p>また、フィールドの組み合わせやリレーション先モデルでフィルタをかけることもできます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Entry</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">search</span><span class=\"o\">=</span><span class=\"n\">SearchVector</span><span class=\"p\">(</span><span class=\"s2\">&quot;blog__tagline&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;body_text&quot;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">search</span><span class=\"o\">=</span><span class=\"s2\">&quot;cheese&quot;</span><span class=\"p\">)</span>\n<span class=\"go\">[</span>\n<span class=\"go\">    &lt;Entry: Cheese on Toast recipes&gt;,</span>\n<span class=\"go\">    &lt;Entry: Pizza Recipes&gt;,</span>\n<span class=\"go\">    &lt;Entry: Dairy farming in Argentina&gt;,</span>\n<span class=\"go\">]</span>\n</code></pre></div>\n<p>詳細は <code class=\"docutils literal notranslate\"><span class=\"pre\">contrib.postgres</span></code> <a class=\"reference internal\" href=\"/ja/6.1/ref/contrib/postgres/search/\"><span class=\"doc\">全文検索</span></a> ドキュメントを参照してください。</p>\n</section>\n</section>\n</section>","rootId":"search","toc":[{"title":"ユースケース","anchor":"use-cases","children":[{"title":"標準的なテキストのクエリ","anchor":"standard-textual-queries","children":[]},{"title":"データベースが持つ高度な比較関数","anchor":"a-database-s-more-advanced-comparison-functions","children":[]},{"title":"文書ベースの検索","anchor":"document-based-search","children":[{"title":"PostgreSQL のサポート","anchor":"postgresql-support","children":[]}]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/6.1/topics/"},{"docname":"topics/db/index","title":"モデルとデータベース","url":"/ja/6.1/topics/db/"}],"prev":{"docname":"topics/db/aggregation","title":"アグリゲーション (集計)","url":"/ja/6.1/topics/db/aggregation/"},"next":{"docname":"topics/db/managers","title":"マネージャ","url":"/ja/6.1/topics/db/managers/"},"formats":{"html":"/ja/6.1/topics/db/search/","markdown":"/ja/6.1/topics/db/search.md","json":"/ja/6.1/topics/db/search.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/topics/db/search.txt","official":"https://docs.djangoproject.com/ja/6.1/topics/db/search/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}