Skip to content

Commit 6e56681

Browse files
committed
docs: add meilisearch hybrid search example
Demonstrates the configurable semanticRatio parameter by comparing results across different ratio values (0.0, 0.5, 1.0) and showing how to override the ratio per query.
1 parent 8ed7f19 commit 6e56681

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
use Symfony\AI\Fixtures\Movies;
13+
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
14+
use Symfony\AI\Store\Bridge\Meilisearch\Store;
15+
use Symfony\AI\Store\Document\Loader\InMemoryLoader;
16+
use Symfony\AI\Store\Document\Metadata;
17+
use Symfony\AI\Store\Document\TextDocument;
18+
use Symfony\AI\Store\Document\Vectorizer;
19+
use Symfony\AI\Store\Indexer;
20+
use Symfony\Component\Uid\Uuid;
21+
22+
require_once dirname(__DIR__).'/bootstrap.php';
23+
24+
echo "=== Meilisearch Hybrid Search Demo ===\n\n";
25+
echo "This example demonstrates how to configure the semantic ratio to balance\n";
26+
echo "between semantic (vector) search and full-text search in Meilisearch.\n\n";
27+
28+
// Initialize the store with a balanced hybrid search (50/50)
29+
$store = new Store(
30+
httpClient: http_client(),
31+
endpointUrl: env('MEILISEARCH_HOST'),
32+
apiKey: env('MEILISEARCH_API_KEY'),
33+
indexName: 'movies_hybrid',
34+
semanticRatio: 0.5, // Balanced hybrid search by default
35+
);
36+
37+
// Create embeddings and documents
38+
$documents = [];
39+
foreach (Movies::all() as $i => $movie) {
40+
$documents[] = new TextDocument(
41+
id: Uuid::v4(),
42+
content: 'Title: '.$movie['title'].\PHP_EOL.'Director: '.$movie['director'].\PHP_EOL.'Description: '.$movie['description'],
43+
metadata: new Metadata($movie),
44+
);
45+
}
46+
47+
// Initialize the index
48+
$store->setup();
49+
50+
// Create embeddings for documents
51+
$platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client());
52+
$vectorizer = new Vectorizer($platform, 'text-embedding-3-small', logger());
53+
$indexer = new Indexer(new InMemoryLoader($documents), $vectorizer, $store, logger: logger());
54+
$indexer->index($documents);
55+
56+
// Create a query embedding
57+
$queryText = 'futuristic technology and artificial intelligence';
58+
echo "Query: \"$queryText\"\n\n";
59+
$queryEmbedding = $vectorizer->vectorize($queryText);
60+
61+
// Test different semantic ratios to compare results
62+
$ratios = [
63+
['ratio' => 0.0, 'description' => '100% Full-text search (keyword matching)'],
64+
['ratio' => 0.5, 'description' => 'Balanced hybrid (50% semantic + 50% full-text)'],
65+
['ratio' => 1.0, 'description' => '100% Semantic search (vector similarity)'],
66+
];
67+
68+
foreach ($ratios as $config) {
69+
echo "--- {$config['description']} ---\n";
70+
71+
// Override the semantic ratio for this specific query
72+
$results = $store->query($queryEmbedding, [
73+
'semanticRatio' => $config['ratio'],
74+
'q' => 'technology', // Full-text search keyword
75+
]);
76+
77+
echo "Top 3 results:\n";
78+
foreach (array_slice($results, 0, 3) as $i => $result) {
79+
$metadata = $result->metadata->getArrayCopy();
80+
echo sprintf(
81+
" %d. %s (Score: %.4f)\n",
82+
$i + 1,
83+
$metadata['title'] ?? 'Unknown',
84+
$result->score ?? 0.0
85+
);
86+
}
87+
echo "\n";
88+
}
89+
90+
echo "--- Custom query with pure semantic search ---\n";
91+
echo "Query: Movies about space exploration\n";
92+
$spaceEmbedding = $vectorizer->vectorize('space exploration and cosmic adventures');
93+
$results = $store->query($spaceEmbedding, [
94+
'semanticRatio' => 1.0, // Pure semantic search
95+
]);
96+
97+
echo "Top 3 results:\n";
98+
foreach (array_slice($results, 0, 3) as $i => $result) {
99+
$metadata = $result->metadata->getArrayCopy();
100+
echo sprintf(
101+
" %d. %s (Score: %.4f)\n",
102+
$i + 1,
103+
$metadata['title'] ?? 'Unknown',
104+
$result->score ?? 0.0
105+
);
106+
}
107+
echo "\n";
108+
109+
// Cleanup
110+
$store->drop();
111+
112+
echo "=== Summary ===\n";
113+
echo "- semanticRatio = 0.0: Best for exact keyword matches\n";
114+
echo "- semanticRatio = 0.5: Balanced approach combining both methods\n";
115+
echo "- semanticRatio = 1.0: Best for conceptual similarity searches\n";
116+
echo "\nYou can set the default ratio when instantiating the Store,\n";
117+
echo "and override it per query using the 'semanticRatio' option.\n";

0 commit comments

Comments
 (0)