Skip to content

djangodocs

Django 6.1
  • 6.1 current
  • 6.0
  • 5.2 LTS
  • 5.1 unsupported
  • 5.0 unsupported
  • 4.2 unsupported
  • 4.1 unsupported
  • 4.0 unsupported
  • 3.2 unsupported
  • 3.1 unsupported
  • 3.0 unsupported
  • 2.2 unsupported
  • 2.1 unsupported
  • 2.0 unsupported
  • 1.11 unsupported
  • 1.10 unsupported
  • 1.9 unsupported
日本語
  • English
  • Svenska
  • 简体中文
  • Gaeilge
  • Français
  • 日本語
  • Bahasa Indonesia
  • Italiano
  • Português (Brasil)
  • 한국어
  • Español
  • Ελληνικά
  • Polski
Documentation contents
  • Django ドキュメント
  • さぁ始めましょう
  • Django を使う
  • How-to ガイド
  • Django FAQ よくある質問
  • API リファレンス
    • アプリケーション
    • システムチェックフレームワーク
    • ビルトインのクラスベースビュー API
    • クリックジャッキング対策
    • contrib パッケージ
      • Django の admin サイト
      • django.contrib.auth
      • contenttypes フレームワーク
      • フラットページ (flatpages) アプリ
      • GeoDjango
      • django.contrib.humanize
      • メッセージフレームワーク
      • django.contrib.postgres
        • PostgreSQL 固有の集計関数
        • PostgreSQL 固有のデータベース制約
        • PostgreSQL 固有のクエリ式
        • PostgreSQL 固有のモデルフィールド
        • PostgreSQL 固有のフォームフィールドとウィジェット
        • PostgreSQL 固有のデータベース関数
        • PostgreSQL 固有のモデルインデックス
        • PostgreSQL 固有のルックアップ
        • データベースのマイグレーション・オペレーション
        • 全文検索
        • バリデータ (Validator)
      • redirects (リダイレクト)アプリ
      • サイトマップ・フレームワーク
      • "sites" フレームワーク
      • staticfiles アプリ
      • 配信 (syndication) フィード フレームワーク
    • コンテンツセキュリティポリシー
    • クロスサイトリクエストフォージェリ (CSRF) 対策
    • データベース
    • django-admin と manage.py
    • Django の例外
    • ファイルの取り扱い
    • フォーム
    • ロギング
    • ミドルウェア
    • マイグレーション・オペレーション
    • モデル
    • ページ分割 (Paginator)
    • リクエストとレスポンスのオブジェクト
    • SchemaEditor
    • 設定
    • シグナル
    • Tasks
    • テンプレート
    • TemplateResponse および SimpleTemplateResponse
    • Unicode データ
    • django.urls ユーティリティ関数
    • URLconf で使用するための django.urls 関数
    • Django ユーティリティ (django.utils)
    • バリデータ (Validator)
    • 組み込みのビュー
  • メタドキュメントとその他
  • 用語集
  • リリースノート
  • Django internals
Japanese translation. Contributed by the Django community. 73.8% Help translate
  1. Django 6.1
  2. API リファレンス
  3. contrib パッケージ
  4. django.contrib.postgres

全文検索Link to this heading#

django.contrib.postgres.search モジュールのデータベース関数は PostgreSQL の 全文検索エンジン を利用しやすくしています。

このドキュメントの例では、 クエリを作成する で定義されたモデルを使用します。

参考

検索の概要については、 トピックのドキュメント を参照してください。

search ルックアップLink to this heading#

全文検索の一般的な使用方法は、データベースの1つのカラムに対して1つの用語を検索することです。たとえば:

Python console
>>> Entry.objects.filter(body_text__search="Cheese")
<QuerySet [<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]>

これにより、データベース内の body_text フィールドから to_tsvector が作成され、検索語 'Cheese' から plainto_tsquery が作成されます。両方ともデフォルトのデータベース検索設定を使用しています。結果は、クエリとベクトルを一致させることで取得されます。

search ルックアップを使用するには、INSTALLED_APPS に 'django.contrib.postgres' を含める必要があります。

SearchVectorLink to this heading#

class SearchVector(*expressions, config=None, weight=None)Link to this definition#

単一のフィールドに対する検索は素晴らしいですが、制約があります。検索対象となる Entry インスタンスは Blog に属しており、 tagline フィールドを持っています。両方のフィールドに対してクエリを行うには、 SearchVector を使用します:

Python console
>>> from django.contrib.postgres.search import SearchVector
>>> Entry.objects.annotate(
...     search=SearchVector("body_text", "blog__tagline"),
... ).filter(search="Cheese")
<QuerySet [<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]>

SearchVector への引数は、任意の Expression またはフィールドの名前を指定できます。複数の引数は、スペースを使用して連結され、検索ドキュメントにすべて含まれます。

SearchVector オブジェクトは組み合わせて再利用できます。たとえば:

Python console
>>> Entry.objects.annotate(
...     search=SearchVector("body_text") + SearchVector("blog__tagline"),
... ).filter(search="Cheese")
<QuerySet [<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]>

config パラメータおよび weight パラメータの説明については、検索設定を変更する と クエリを重み付けする を参照してください。

SearchQueryLink to this heading#

class SearchQuery(value, config=None, search_type='plain')Link to this definition#

SearchQuery は、ユーザーが提供した用語を検索クエリオブジェクトに変換し、データベースが検索ベクトルと比較する機能を提供します。デフォルトでは、ユーザーが提供したすべての単語がステミングアルゴリズムを通過され、その結果の用語すべてに一致するものを検索します。

もし search_type が 'plain' (デフォルト) の場合、用語は別々のキーワードとして扱われます。もし search_type が 'phrase' の場合、用語は1つのフレーズとして扱われます。もし search_type が 'raw' の場合、用語と演算子を含む書式付きの検索クエリを指定できます。もし search_type が 'websearch' の場合、Web検索エンジンで使用されるものに類似した書式で検索クエリを指定できます。 'websearch' には PostgreSQL ≥ 11 が必要です。違いや構文については PostgreSQL の Full Text Search docs を参照してください。例:

Python console
>>> from django.contrib.postgres.search import SearchQuery, Lexeme
>>> SearchQuery("red tomato")  # two keywords
>>> SearchQuery("tomato red")  # same results as above
>>> SearchQuery("red tomato", search_type="phrase")  # a phrase
>>> SearchQuery("tomato red", search_type="phrase")  # a different phrase
>>> SearchQuery("'tomato' & ('red' | 'green')", search_type="raw")  # boolean operators
>>> SearchQuery(
...     "'tomato' ('red' OR 'green')", search_type="websearch"
... )  # websearch operators
>>> SearchQuery(Lexeme("tomato") & (Lexeme("red") | Lexeme("green")))  # Lexeme objects

SearchQuery の用語は論理的に組み合わせることで、柔軟性を高めることができます:

Python console
>>> from django.contrib.postgres.search import SearchQuery
>>> SearchQuery("meat") & SearchQuery("cheese")  # AND
>>> SearchQuery("meat") | SearchQuery("cheese")  # OR
>>> ~SearchQuery("meat")  # NOT

config パラメータの説明については、検索設定を変更する を参照してください。

Changed in Django 6.0

Lexeme オブジェクトが追加されました。

SearchRankLink to this heading#

class SearchRank(vector, query, weights=None, normalization=None, cover_density=False)Link to this definition#

これまでに、ベクトルとクエリの間で一致する結果を返してきました。おそらく結果をある種の関連性によって並べ替えたいと思うかもしれません。PostgreSQLにはランキング関数が用意されており、クエリ用語がドキュメント内にどれだけ多く現れるか、用語がドキュメント内でどれだけ近くにあるか、そしてそれらが発生するドキュメント内の部分がどれだけ重要かを考慮します。一致度が高いほど、ランクの値が高くなります。関連度で並び替えるには:

Python console
>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
>>> vector = SearchVector("body_text")
>>> query = SearchQuery("cheese")
>>> Entry.objects.annotate(rank=SearchRank(vector, query)).order_by("-rank")
<QuerySet [<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]>

weights パラメータの説明については、クエリを重み付けする を参照してください。

cover_density パラメーターを True に設定して、カバー密度ランキングを有効にします。これにより、クエリ用語の一致する近接度が考慮されます。

normalization パラメータに整数を指定すると、順位の正規化を制御できます。この整数はビットマスクであり、複数の動作を組み合わせることができます。

Python console
>>> from django.db.models import Value
>>> Entry.objects.annotate(
...     rank=SearchRank(
...         vector,
...         query,
...         normalization=Value(2).bitor(Value(4)),
...     )
... )

PostgreSQLのドキュメントに、 different rank normalization options についての詳細があります。

SearchHeadlineLink to this heading#

class SearchHeadline(expression, query, config=None, start_sel=None, stop_sel=None, max_words=None, min_words=None, short_word=None, highlight_all=None, max_fragments=None, fragment_delimiter=None)Link to this definition#

単一のテキストフィールドまたは式、クエリ、設定、およびオプションのセットを受け入れ、ハイライトされた検索結果を返します。

start_sel パラメータと stop_sel パラメータには、ハイライトされたクエリ語をドキュメントで囲むために使用する文字列値を設定します。PostgreSQLのデフォルトは <b> と </b> です。

パラメータ max_words と min_words に整数値を指定して、最長と最短の見出しを決定します。PostgreSQLのデフォルトは35と15です。

short_word パラメータに整数値を指定すると、各見出しでこの長さ以下の単語を破棄します。PostgreSQLのデフォルトは3です。

highlight_all パラメータを True に設定すると、フラグメントの代わりにドキュメント全体を使用し、 max_words、min_words、short_word パラメータを無視します。PostgreSQLではデフォルトで無効になっています。

表示するフラグメントの最大数を設定するには、 max_fragments に0以外の整数値を指定してください。PostgreSQLではデフォルトで無効になっています。

fragment_delimiter 文字列パラメータを設定すると、フラグメント間の区切り文字を構成できます。PostgreSQL のデフォルトは " ... " です。

PostgreSQL のドキュメントには、highlighting search results に関する詳細が記載されています。

使用例:

Python console
>>> from django.contrib.postgres.search import SearchHeadline, SearchQuery
>>> query = SearchQuery("red tomato")
>>> entry = Entry.objects.annotate(
...     headline=SearchHeadline(
...         "body_text",
...         query,
...         start_sel="<span>",
...         stop_sel="</span>",
...     ),
... ).get()
>>> print(entry.headline)
Sandwich with <span>tomato</span> and <span>red</span> cheese.

config パラメータの説明については、検索設定を変更する を参照してください。

検索設定を変更するLink to this heading#

SearchVector および SearchQuery に config 属性を指定して、異なる検索設定を使用できます。これにより、データベースで定義された異なる言語の解析機能や辞書を使用できます。

Python console
>>> from django.contrib.postgres.search import SearchQuery, SearchVector
>>> Entry.objects.annotate(
...     search=SearchVector("body_text", config="french"),
... ).filter(search=SearchQuery("œuf", config="french"))
<QuerySet [<Entry: Pain perdu>]>

config の値は別の列にも保存できます。

Python console
>>> from django.db.models import F
>>> Entry.objects.annotate(
...     search=SearchVector("body_text", config=F("blog__language")),
... ).filter(search=SearchQuery("œuf", config=F("blog__language")))
<QuerySet [<Entry: Pain perdu>]>

クエリを重み付けするLink to this heading#

すべてのフィールドがクエリにおいて同じ重要度を持つとは限りません。そのため、それらを組み合わせる前に、複数のベクトルの重みを設定できます。

Python console
>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
>>> vector = SearchVector("body_text", weight="A") + SearchVector(
...     "blog__tagline", weight="B"
... )
>>> query = SearchQuery("cheese")
>>> Entry.objects.annotate(rank=SearchRank(vector, query)).filter(rank__gte=0.3).order_by(
...     "rank"
... )

重みは次のいずれかの文字である必要があります: D, C, B, A。デフォルトでは、これらの重みはそれぞれ 0.1, 0.2, 0.4, 1.0 に対応しています。異なる重みを使用する場合は、同じ順序で四つの浮動小数点数のリストを、上記の通りに SearchRank に weights として渡してください。

Python console
>>> rank = SearchRank(vector, query, weights=[0.2, 0.4, 0.6, 0.8])
>>> Entry.objects.annotate(rank=rank).filter(rank__gte=0.3).order_by("-rank")

LexemeLink to this heading#

New in Django 6.0

class Lexeme(value, output_field=None, *, invert=False, prefix=False, weight=None)Link to this definition#

Lexeme objects allow search operators to be safely used with strings from an untrusted source. The content of each lexeme is escaped so that any operators that may exist in the string itself will not be interpreted.

You can combine lexemes with other lexemes using the & and | operators and also negate them with the ~ operator. For example:

Python console
>>> from django.contrib.postgres.search import SearchQuery, SearchVector, Lexeme
>>> vector = SearchVector("body_text", "blog__tagline")
>>> Entry.objects.annotate(search=vector).filter(
...     search=SearchQuery(Lexeme("fruit") & Lexeme("dessert"))
... )
<QuerySet [<Entry: Apple Crumble Recipes>, <Entry: Banana Split Recipes>]>
Python console
>>> Entry.objects.annotate(search=vector).filter(
...     search=SearchQuery(Lexeme("fruit") & Lexeme("dessert") & ~Lexeme("banana"))
... )
<QuerySet [<Entry: Apple Crumble Recipes>]>

Lexeme objects also support term weighting and prefixes:

Python console
>>> Entry.objects.annotate(search=vector).filter(
...     search=SearchQuery(Lexeme("Pizza") | Lexeme("Cheese"))
... )
<QuerySet [<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]>
>>> Entry.objects.annotate(search=vector).filter(
...     search=SearchQuery(Lexeme("Pizza") | Lexeme("Cheese", weight="A"))
... )
<QuerySet [<Entry: Pizza recipes>]>
>>> Entry.objects.annotate(search=vector).filter(
...     search=SearchQuery(Lexeme("za", prefix=True))
... )
<QuerySet []>

パフォーマンスLink to this heading#

これらの関数を使用するために特別なデータベース設定をする必要はありませんが、数百以上のレコードを検索する場合、パフォーマンスの問題に直面する可能性が高くなります。全文検索は、例えば整数のサイズを比較するよりも負荷の高い処理です。

In the event that all the fields you're querying on are contained within one particular model, you can create a functional GinIndex or GistIndex which matches the search vector you wish to use. For example:

Code
GinIndex(
    SearchVector("body_text", "headline", config="english"),
    name="search_vector_idx",
)

The PostgreSQL docs has details on creating indexes for full text search.

SearchVectorFieldLink to this heading#

class SearchVectorFieldLink to this definition#

この方法が遅すぎる場合は、モデルに SearchVectorField を追加できます。このフィールドには、例えば PostgreSQL documentation で説明されているように、トリガーを入力しておく必要があります。そうすれば、あたかもアノテーションされた SearchVector のようにフィールドに問い合わせることができます:

Python console
>>> Entry.objects.update(search_vector=SearchVector("body_text"))
>>> Entry.objects.filter(search_vector="cheese")
<QuerySet [<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]>

Using GeneratedFieldLink to this heading#

An alternative method is to use a GeneratedField, which has PostgreSQL maintain the column rather than a trigger:

Code
from django.contrib.postgres.indexes import GinIndex
from django.contrib.postgres.search import SearchVector, SearchVectorField
from django.db import models


class Entry(models.Model):
    headline = models.CharField(max_length=255)
    body_text = models.TextField()

    search_vector = models.GeneratedField(
        expression=SearchVector("headline", weight="A", config="english")
        + SearchVector("body_text", weight="B", config="english"),
        output_field=SearchVectorField(),
        db_persist=True,
    )

    class Meta:
        indexes = [GinIndex(fields=["search_vector"])]

trigram(トリグラム)類似度Link to this heading#

検索の別の手法として trigram 類似度があります。trigram は3つの連続する文字のグループです。 trigram_similar、trigram_word_similar、trigram_strict_word_similar の他にもいくつかの式を使用できます。

これらを使用するには、PostgreSQL上で pg_trgm 拡張機能 を有効にする必要があります。これは、 TrigramExtension マイグレーション・オペレーションを使用してインストールできます。

TrigramSimilarityLink to this heading#

class TrigramSimilarity(expression, string, **extra)Link to this definition#

フィールド名や式、文字列や式を受け取ります。2つの引数の間の trigram 類似度を返します。

使用例:

Python console
>>> from django.contrib.postgres.search import TrigramSimilarity
>>> Author.objects.create(name="Katy Stevens")
>>> Author.objects.create(name="Stephen Keats")
>>> test = "Katie Stephens"
>>> Author.objects.annotate(
...     similarity=TrigramSimilarity("name", test),
... ).filter(
...     similarity__gt=0.3
... ).order_by("-similarity")
<QuerySet [<Author: Katy Stevens>, <Author: Stephen Keats>]>

TrigramWordSimilarityLink to this heading#

class TrigramWordSimilarity(string, expression, **extra)Link to this definition#

文字列または式、およびフィールド名または式を受け入れます。2つの引数間の trigram 単語類似度を返します。

使用例:

Python console
>>> from django.contrib.postgres.search import TrigramWordSimilarity
>>> Author.objects.create(name="Katy Stevens")
>>> Author.objects.create(name="Stephen Keats")
>>> test = "Kat"
>>> Author.objects.annotate(
...     similarity=TrigramWordSimilarity(test, "name"),
... ).filter(
...     similarity__gt=0.3
... ).order_by("-similarity")
<QuerySet [<Author: Katy Stevens>]>

TrigramStrictWordSimilarityLink to this heading#

class TrigramStrictWordSimilarity(string, expression, **extra)Link to this definition#

文字列または式とフィールド名または式を受け取り、2つの引数間の trigram 厳密単語類似度を返します。 TrigramWordSimilarity() と似ていますが、この関数は範囲境界を単語境界と一致させるように強制します。

TrigramDistanceLink to this heading#

class TrigramDistance(expression, string, **extra)Link to this definition#

フィールド名または式と、文字列または式を受け入れます。2つの引数の間の trigram 距離を返します。

使用例:

Python console
>>> from django.contrib.postgres.search import TrigramDistance
>>> Author.objects.create(name="Katy Stevens")
>>> Author.objects.create(name="Stephen Keats")
>>> test = "Katie Stephens"
>>> Author.objects.annotate(
...     distance=TrigramDistance("name", test),
... ).filter(
...     distance__lte=0.7
... ).order_by("distance")
<QuerySet [<Author: Katy Stevens>, <Author: Stephen Keats>]>

TrigramWordDistanceLink to this heading#

class TrigramWordDistance(string, expression, **extra)Link to this definition#

文字列または式と、フィールド名または式を受け取ります。2つの引数間の trigram 単語距離を返します。

使用例:

Python console
>>> from django.contrib.postgres.search import TrigramWordDistance
>>> Author.objects.create(name="Katy Stevens")
>>> Author.objects.create(name="Stephen Keats")
>>> test = "Kat"
>>> Author.objects.annotate(
...     distance=TrigramWordDistance(test, "name"),
... ).filter(
...     distance__lte=0.7
... ).order_by("distance")
<QuerySet [<Author: Katy Stevens>]>

TrigramStrictWordDistanceLink to this heading#

class TrigramStrictWordDistance(string, expression, **extra)Link to this definition#

文字列または式、フィールド名または式を受け入れ、これらの引数間の trigram strict 単語距離を返します。

View as Markdown Edit this page on GitHub Official version
Previousデータベースのマイグレーション・オペレーション Nextバリデータ (Validator)

On this page

  • search ルックアップ
  • SearchVector
  • SearchQuery
  • SearchRank
  • SearchHeadline
  • 検索設定を変更する
  • クエリを重み付けする
  • Lexeme
  • パフォーマンス
    • SearchVectorField
    • Using GeneratedField
  • trigram(トリグラム)類似度
    • TrigramSimilarity
    • TrigramWordSimilarity
    • TrigramStrictWordSimilarity
    • TrigramDistance
    • TrigramWordDistance
    • TrigramStrictWordDistance

An unofficial rendering of the Django documentation.

Not affiliated with or endorsed by the Django Software Foundation. The documentation is copyright © Django Software Foundation and individual contributors, and is used under the BSD 3-Clause licence. “Django” is a trademark of the Django Software Foundation.

This translation is the work of the Django i18n community, not of this site. Read the official documentation at docs.djangoproject.com.

👋 Jason Cartwright