{"title":"検索","version":"2.2","locale":"ja","docname":"topics/db/search","url":"/ja/2.2/topics/db/search/","canonical":"https://djangodocs.dev/ja/2.2/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/2.2/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>テキストベースのフィールドには、単純な一致検索のオペレーションがあります。たとえば、著者に対する検索は次のように実現したいと思うかもしれません。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code 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=\"s1\">&#39;Terry&#39;</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/2.2/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>If you're using PostgreSQL, Django provides <a class=\"reference internal\" href=\"/ja/2.2/ref/contrib/postgres/search/\"><span class=\"doc\">a selection of database\nspecific tools</span></a> to allow you to leverage more\ncomplex querying options. Other databases have different selections of tools,\npossibly via plugins or user-defined functions. Django doesn't include any\nsupport for them at this time. We'll use some examples from PostgreSQL to\ndemonstrate the kind of functionality databases may have.</p>\n<aside class=\"admonition-searching-in-other-databases admonition\">\n<p class=\"admonition-title\">Searching in other databases</p>\n<p>All of the searching tools provided by <a class=\"reference internal\" href=\"/ja/2.2/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> are\nconstructed entirely on public APIs such as <a class=\"reference internal\" href=\"/ja/2.2/ref/models/lookups/\"><span class=\"doc\">custom lookups</span></a> and <a class=\"reference internal\" href=\"/ja/2.2/ref/models/database-functions/\"><span class=\"doc\">database functions</span></a>. Depending on your database, you should\nbe able to construct queries to allow similar APIs. If there are specific\nthings which cannot be achieved this way, please open a ticket.</p>\n</aside>\n<p>In the above example, we determined that a case insensitive lookup would be\nmore useful. When dealing with non-English names, a further improvement is to\nuse <a class=\"reference internal\" href=\"/ja/2.2/ref/contrib/postgres/lookups/#std-fieldlookup-unaccent\"><code class=\"xref std std-lookup docutils literal notranslate\"><span class=\"pre\">unaccented</span> <span class=\"pre\">comparison</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code 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=\"s1\">&#39;Helen&#39;</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>This shows another issue, where we are matching against a different spelling of\nthe name. In this case we have an asymmetry though - a search for <code class=\"docutils literal notranslate\"><span class=\"pre\">Helen</span></code>\nwill pick up <code class=\"docutils literal notranslate\"><span class=\"pre\">Helena</span></code> or <code class=\"docutils literal notranslate\"><span class=\"pre\">Hélène</span></code>, but not the reverse. Another option\nwould be to use a <a class=\"reference internal\" href=\"/ja/2.2/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> comparison, which compares\nsequences of letters.</p>\n<p>例:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code 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=\"s1\">&#39;Hélène&#39;</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>Now we have a different problem - the longer name of &quot;Helena Bonham Carter&quot;\ndoesn't show up as it is much longer. Trigram searches consider all\ncombinations of three letters, and compares how many appear in both search and\nsource strings. For the longer name, there are more combinations which appear\nin the source string so it is no longer considered a close match.</p>\n<p>The correct choice of comparison functions here depends on your particular data\nset, for example the language(s) used and the type of text being searched. All\nof the examples we've seen are on short strings where the user is likely to\nenter something close (by varying definitions) to the source data.</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>Simple database operations are too simple an approach when you start\nconsidering large blocks of text. Whereas the examples above can be thought of\nas operations on a string of characters, full text search looks at the actual\nwords. Depending on the system used, it's likely to use some of the following\nideas:</p>\n<ul class=\"simple\">\n<li><p>Ignoring &quot;stop words&quot; such as &quot;a&quot;, &quot;the&quot;, &quot;and&quot;.</p></li>\n<li><p>Stemming words, so that &quot;pony&quot; and &quot;ponies&quot; are considered similar.</p></li>\n<li><p>Weighting words based on different criteria such as how frequently they\nappear in the text, or the importance of the fields, such as the title or\nkeywords, that they appear in.</p></li>\n</ul>\n<p>There are many alternatives for using searching software, some of the most\nprominent are <a class=\"reference external\" href=\"https://www.elastic.co/\">Elastic</a> and <a class=\"reference external\" href=\"https://lucene.apache.org/solr/\">Solr</a>. These are full document-based search\nsolutions. To use them with data from Django models, you'll need a layer which\ntranslates your data into a textual document, including back-references to the\ndatabase ids. When a search using the engine returns a certain document, you\ncan then look it up in the database. There are a variety of third-party\nlibraries which are designed to help with this process.</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 has its own full text search implementation built-in. While not as\npowerful as some other search engines, it has the advantage of being inside\nyour database and so can easily be combined with other relational queries such\nas categorization.</p>\n<p>The <a class=\"reference internal\" href=\"/ja/2.2/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> module provides some helpers to make these\nqueries. For example, a simple query might be to select all the blog entries\nwhich mention &quot;cheese&quot;:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code 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=\"s1\">&#39;cheese&#39;</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>You can also filter on a combination of fields and on related models:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</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=\"Code 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=\"s1\">&#39;blog__tagline&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;body_text&#39;</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=\"s1\">&#39;cheese&#39;</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>See the <code class=\"docutils literal notranslate\"><span class=\"pre\">contrib.postgres</span></code> <a class=\"reference internal\" href=\"/ja/2.2/ref/contrib/postgres/search/\"><span class=\"doc\">Full text search</span></a> document for\ncomplete details.</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/2.2/topics/"},{"docname":"topics/db/index","title":"モデルとデータベース","url":"/ja/2.2/topics/db/"}],"prev":{"docname":"topics/db/aggregation","title":"アグリゲーション","url":"/ja/2.2/topics/db/aggregation/"},"next":{"docname":"topics/db/managers","title":"マネージャ","url":"/ja/2.2/topics/db/managers/"},"formats":{"html":"/ja/2.2/topics/db/search/","markdown":"/ja/2.2/topics/db/search.md","json":"/ja/2.2/topics/db/search.json"},"source":"https://github.com/django/django/blob/stable/2.2.x/docs/topics/db/search.txt","official":"https://docs.djangoproject.com/ja/2.2/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","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}