メインコンテンツまでスキップ

テキスト検索

概要

テキスト検索は特定の用語やフレーズを含むドキュメントを取得し、関連性によって結果をランク付けします。

セマンティック類似性を通じてリコールを拡張することで「幅広く見つけること」に優れたベクトル検索と比較して、テキスト検索はキーワードヒットと決定論的フィルタを保証する制御可能で説明可能な完全一致を提供することで「正確に見つけること」に優れています。

生成AI アプリケーション、特にRetrieval‑Augmented Generation (RAG) において、テキスト検索とベクトル検索は相互に補完します。両者が連携することで、セマンティックな幅と語彙的な精度のバランスを取り、精度と解釈可能性を確保しながらリコールを改善し、モデルにより正確で関連性の高いコンテキストを提供する信頼性の高い検索基盤を構築します。

Doris テキスト検索の進化

バージョン2.0.0以降、Dorisは多様な検索シナリオと増大するクエリの複雑さに対応するため、テキスト検索を導入し継続的に拡張してきました。

基盤 (2.0+)

基本的なフルテキスト演算子 (MATCH_ANY、MATCH_ALL) と多言語トークナイザーを備えた列レベルの転置インデックスにより、大規模データセットでの効率的なキーワード検索が可能になります。

機能拡張 (2.x → 3.x)

充実した演算子セットにより、フレーズマッチング (MATCH_PHRASE)、前置詞検索 (MATCH_PHRASE_PREFIX)、正規表現マッチング (MATCH_REGEXP) が追加されます。バージョン3.1では、多様なテキスト解析ニーズに対応するためのカスタムアナライザーが導入されます。

機能強化 (4.0+)

テキスト検索に関連性スコアリングと統一検索エントリが追加され、BM25スコアリングとSEARCH関数が正式に導入されます。

  • BM25関連性スコアリング:score() でテキストの関連性による結果のランク付け、およびハイブリッドランキングのためのベクトル類似度との統合。

  • SEARCH関数:列をまたがる検索とブール論理をサポートする統一クエリDSLにより、パフォーマンスを向上させながら複雑なクエリ構築を簡素化。

コアテキスト検索機能

豊富なテキスト演算子

Dorisは、キーワードマッチングから高度なフレーズクエリまで、複数の検索パターンをカバーするフルテキスト演算子のセットを提供します。

主要な演算子には以下があります:

  • MATCH_ANY / MATCH_ALL:一般的なキーワード検索のためのOR/AND複数語マッチング
  • MATCH_PHRASE:設定可能なslopと順序制御による完全フレーズ
  • MATCH_PHRASE_PREFIX:オートコンプリートと増分検索のためのフレーズ前置詞マッチング
  • MATCH_REGEXP:パターンベース検索のためのトークン化された語句での正規表現

演算子は単独で使用することも、SEARCH() を介して組み合わせて複雑なロジックを構築することもできます。例:

-- Keyword search (any keyword match)
SELECT * FROM docs WHERE content MATCH_ANY 'apache doris database';

-- Require all keywords
SELECT * FROM docs WHERE content MATCH_ALL 'real-time analytics OLAP';

-- Exact phrase
SELECT * FROM docs WHERE content MATCH_PHRASE 'inverted index';

-- Phrase with slop (allow up to 2 words between terms)
SELECT * FROM docs WHERE content MATCH_PHRASE 'machine learning ~2';

-- Prefix matching
SELECT * FROM docs WHERE content MATCH_PHRASE_PREFIX 'data ware'; -- matches "data warehouse", "data warehousing"

すべての演算子を見る →

Custom Analyzers (3.1+)

トークン化戦略は適合率と再現率の両方に直接影響します。3.1以降、Dorisはcustom analyzersをサポートしており、char_filtertokenizertoken_filterを組み合わせて解析パイプラインを定義できます。

典型的な使用例には以下が含まれます:

  • トークン化前の置換/正規化のためのカスタム文字フィルタリング
  • 異なる言語やテキスト形式に対してstandardngramedge_ngramkeywordicuなどのtokenizerの選択
  • トークンを正規化し精緻化するためのlowercaseword_delimiterascii_foldingなどのtoken filterの適用
-- Define a custom analyzer
CREATE INVERTED INDEX ANALYZER IF NOT EXISTS keyword_lowercase
PROPERTIES (
"tokenizer" = "keyword",
"token_filter" = "asciifolding, lowercase"
);

-- Use the analyzer in table creation
CREATE TABLE docs (
id BIGINT,
content TEXT,
INDEX idx_content (content) USING INVERTED PROPERTIES (
"analyzer" = "keyword_lowercase",
"support_phrase" = "true"
)
);

カスタムアナライザーについて学ぶ →

BM25 関連性スコアリング (4.0+)

Dorisはテキスト関連性スコアリングのために**BM25 (Best Matching 25)**アルゴリズムを実装しており、検索結果のTop-Nランキングを可能にします:

主要機能:

  • 用語頻度、逆文書頻度、文書長に基づく確率的ランキング
  • 長い文書と短い文書の両方の堅牢な処理
  • ランキング動作のための調整可能なパラメータ (k1, b)
  • Top-Nクエリとのシームレスな統合

使用パターン:

SELECT id, title, score() AS relevance
FROM docs
WHERE content MATCH_ANY 'real-time OLAP analytics'
ORDER BY relevance DESC
LIMIT 10;

動作原理:

  • score() はマッチした各行のBM25スコアを計算します
  • 高いスコアは、クエリ条件により強い関連性を示します
  • 効率的なTop-N取得のため、ORDER BYLIMITと組み合わせます
  • すべてのMATCH_*演算子とSEARCH()関数で動作します

スコアリングの詳細 →

SEARCH関数: 統合クエリDSL (4.0+)

SEARCH()関数は、複雑なテキストクエリのための簡潔で表現力豊かな構文を提供します:

基本構文:

SEARCH('column:term')                          -- Single term
SEARCH('column:ANY(term1 term2)') -- Any of the terms (OR)
SEARCH('column:ALL(term1 term2)') -- All terms (AND)
SEARCH('column:EXACT(exact text)') -- Case-sensitive exact match

Boolean合成:

SEARCH('title:apache AND category:database')
SEARCH('title:doris OR title:clickhouse')
SEARCH('tags:ANY(olap analytics) AND NOT status:deprecated')

複数列クエリ:

SEARCH('title:search AND (content:engine OR tags:ANY(elasticsearch lucene))')

半構造化データ:

SEARCH('properties.user.name:alice')           -- Variant subcolumn access

スコアリングあり:

SELECT id, title, score() AS relevance
FROM docs
WHERE SEARCH('title:Machine AND tags:ANY(database sql)')
ORDER BY relevance DESC
LIMIT 20;

完全なSEARCH機能ガイド →

クイックスタート

ステップ1: 転置インデックス付きテーブルの作成

CREATE TABLE docs (
id BIGINT,
title STRING,
content STRING,
category STRING,
tags ARRAY<STRING>,
created_at DATETIME,
-- Text search indexes
INDEX idx_title(title) USING INVERTED PROPERTIES ("parser" = "english"),
INDEX idx_content(content) USING INVERTED PROPERTIES ("parser" = "english", "support_phrase" = "true"),
INDEX idx_category(category) USING INVERTED,
INDEX idx_tags(tags) USING INVERTED
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 10;

ステップ2: テキストクエリの実行

-- Simple keyword search
SELECT * FROM docs WHERE content MATCH_ANY 'apache doris';

-- Phrase search
SELECT * FROM docs WHERE content MATCH_PHRASE 'full text search';

-- Boolean query with SEARCH
SELECT * FROM docs
WHERE SEARCH('title:apache AND (category:database OR tags:ANY(sql nosql))');

-- Relevance-based ranking
SELECT id, title, score() AS relevance
FROM docs
WHERE content MATCH_ANY 'real-time analytics OLAP'
ORDER BY relevance DESC
LIMIT 10;

ハイブリッド検索: テキスト + ベクター

RAGアプリケーションにおける包括的な検索のために、テキスト検索とベクター類似性を組み合わせます:

-- Hybrid retrieval: semantic similarity + keyword filtering
SELECT id, title, score() AS text_relevance
FROM docs
WHERE
-- Vector filter for semantic similarity
cosine_distance(embedding, [0.1, 0.2, ...]) < 0.3
-- Text filter for keyword constraints
AND SEARCH('title:search AND content:engine AND category:technology')
ORDER BY text_relevance DESC
LIMIT 10;

転置インデックスの管理

インデックスの作成

-- At table creation
CREATE TABLE t (
content STRING,
INDEX idx(content) USING INVERTED PROPERTIES ("parser" = "english")
);

-- On existing table
CREATE INDEX idx_content ON docs(content) USING INVERTED PROPERTIES ("parser" = "chinese");

-- Build index for existing data
BUILD INDEX idx_content ON docs;

インデックスの削除

DROP INDEX idx_content ON docs;

インデックスの表示

SHOW CREATE TABLE docs;
SHOW INDEX FROM docs;

Index管理ガイド →

詳細情報

コアドキュメント

高度なトピック

  • カスタムAnalyzer — ドメイン固有のトークナイザーとフィルターの構築
  • Vector Search — 埋め込みを使用したセマンティック類似性検索