Skip to content

djangodocs

Django 5.2
  • 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 を使う
    • Django のインストール方法
    • モデルとデータベース
      • モデル
      • クエリを作成する
      • アグリゲーション (集計)
      • 検索
      • マネージャ
      • 素の SQL 文の実行
      • データベースのトランザクション
      • 複数のデータベース
      • テーブル空間(tablespace)
      • データベースアクセスの最適化
      • データベースの計測
      • フィクスチャ (fixture)
      • モデルリレーションシップ API の使用例
    • HTTP リクエストのハンドリング
    • フォームを使う
    • テンプレート
    • クラスベースビュー
    • マイグレーション
    • ファイルの管理
    • Django におけるテスト
    • Django でのユーザー認証
    • Django のキャッシュフレームワーク
    • 条件付きのビュー処理
    • 複合主キー
    • 暗号署名
    • メールを送信する
    • 国際化とローカライズ
    • ロギング
    • ページ分割 (Pagination)
    • Django におけるセキュリティ
    • パフォーマンスと最適化
    • Django オブジェクトのシリアライズ
    • Djangoの設定
    • シグナル
    • システムチェックフレームワーク
    • 外部パッケージ
    • 非同期サポート
  • How-to ガイド
  • Django FAQ よくある質問
  • API リファレンス
  • メタドキュメントとその他
  • 用語集
  • リリースノート
  • Django internals
Japanese translation. Contributed by the Django community. 77.5% Help translate
  1. Django 5.2
  2. Django を使う
  3. モデルとデータベース

検索Link to this heading#

ウェブアプリケーションの一般的なタスクは、ユーザーからの入力を用いてデータベース内のデータを検索することです。簡単なケースなら、オブジェクトのリストをカテゴリごとにフィルタリングすることで実現できるかもしれません。しかし、もっと複雑なユースケースでは、重み付き検索、カテゴリー分け、ハイライト、複数言語対応などが必要になることもあります。このドキュメントでは、そのようなユースケースについて説明するとともに、利用できるツールを紹介します。

ここでは クエリを作成する で使われたのと同じモデルを使って説明します。

ユースケースLink to this heading#

標準的なテキストのクエリLink to this heading#

テキストベースのフィールドには、マッチング処理の選択肢があります。たとえば、次のように著者をルックアップしたいと思うかも知れません:

Python console
>>> Author.objects.filter(name__contains="Terry")
[<Author: Terry Gilliam>, <Author: Terry Jones>]

これは非常に弱い解決方法です。なぜなら、ユーザーが著者名の正確な部分文字列を知っている必要があるからです。case-insensitive なマッチ (icontains) を利用すれば少しはましになりますが、ほとんど違いはありません。

データベースが持つ高度な比較関数Link to this heading#

PostgreSQL を使っている場合、 Django は データベース固有のツールの選択肢 があり、より複雑なクエリオプションが利用できます。他のデータベースでは、プラグインやユーザ定義関数を使うことで、様々なツ ールを選択できます。Django は今のところ、そのようなツールをサポートしていません。PostgreSQL の例をいくつか使って、データベースがどのような機能を持っているかを説明します。

他のデータベースにおける検索

django.contrib.postgres が提供するすべての検索ツールは、 カスタムルックアップ や データベース関数 のようなパブリック API を利用して構築されています。データベースによっては、同様のAPIを許可するクエリを構築できるはずです。この方法で実現できない特定のことがあれば、チケットをオープンしてください。

上記の例では、大文字と小文字を区別しないルックアップがの方が使いやすいでしょう。英語以外の名前を扱う場合、さらなる改善は アクセントなし比較 を使うことです:

Python console
>>> Author.objects.filter(name__unaccent__icontains="Helen")
[<Author: Helen Mirren>, <Author: Helena Bonham Carter>, <Author: Hélène Joy>]

これには別の問題があります。異なる綴りの名前とマッチする場合です。 Helen を検索すると Helena や Hélène がヒットしますが、その逆はヒットしません。もう一つの方法は trigram_similar 比較を使うことです。

例えば次のようにします:

Python console
>>> Author.objects.filter(name__unaccent__lower__trigram_similar="Hélène")
[<Author: Helen Mirren>, <Author: Hélène Joy>]

今度は別の問題です。"Helena Bonham Carter "という長い名前は、もっと長いので表示されません。trigram 検索では、3文字のすべての組み合わせを考慮し、検索文字列とソース文字列の両方で何回現れるかを比較します。より長い名前では、ソース文字列に現れない組み合わせが多くなるため、近接一致とは見なされなくなります。

ここでの比較関数の正しい選択は、使用されている言語や検索されるテキストのタイプなど、データセットによって異なります。これまで見てきた例はすべて、ユーザーがソースデータに近いものを(さまざまな定義で)入力する可能性が高い短い文字列に関するものです。

文書ベースの検索Link to this heading#

標準的なデータベース操作は、大きなテキストブロックを考慮し始めると、有用なアプローチではなくなります。上記の例は文字列に対する操作と考えることができますが、全文検索は実際の単語を調べます。使用するシステムにもよりますが、以下のような考え方が使われるでしょう:

  • "a", "the", "and "などの "ストップワード" は無視する。

  • "pony" と "ponies" が似ているとみなされるように、単語のステミング(Stemming)を行う。

  • テキスト内での出現頻度や、タイトルやキーワードのようなフィールドの重要性に基づいて単語に重みを付けるなど、異なる基準に基づいて単語を重み付けする。

検索ソフトウェアを使用するための代替手段は数多くありますが、その中でも最も有名なものに Elastic と Solr があります。これらは完全なドキュメントベースの検索ソリューションです。Django モデルからのデータでこれらを使うには、データベース ID への後方参照を含め、データをテキスト文書に変換するレイヤが必要です。このエンジンを使って検索すると、特定の文書が返され、それをデータベースで調べることができます。このプロセスを支援するために設計された、さまざまなサードパーティライブラリがあります。

PostgreSQL のサポートLink to this heading#

PostgreSQLには独自の全文検索実装が組み込まれています。他の検索エンジンほど強力ではありませんが、データベース内にあるため、カテゴリ分類などの他のリレーショナルクエリと簡単に組み合わせることができるという利点があります。

django.contrib.postgres モジュールは、これらのクエリを作成するためのヘルパーをいくつか提供しています。例えば、"cheese" に言及している全てのブログエントリを選択するクエリがあります:

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

また、フィールドの組み合わせやリレーション先モデルでフィルタをかけることもできます:

Python console
>>> Entry.objects.annotate(
...     search=SearchVector("blog__tagline", "body_text"),
... ).filter(search="cheese")
[
    <Entry: Cheese on Toast recipes>,
    <Entry: Pizza Recipes>,
    <Entry: Dairy farming in Argentina>,
]

詳細は contrib.postgres 全文検索 ドキュメントを参照してください。

View as Markdown Edit this page on GitHub Official version
Previousアグリゲーション (集計) Nextマネージャ

On this page

  • ユースケース
    • 標準的なテキストのクエリ
    • データベースが持つ高度な比較関数
    • 文書ベースの検索
      • PostgreSQL のサポート

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