Try Vector Search in Google Colab — One Cell at a Time
Want to try vector search, but don't want to set up a vector database or search server?
With nlp4j-local-search 0.8.0.0, you can try semantic vector search directly in Google Colab.
No Elasticsearch.
No OpenSearch.
No vector database server.
No Docker.
Just open a Colab notebook and run the Python code one cell at a time.
This is intended as a small experiment rather than a full application. If you are curious about vector search or want to understand the retrieval part of RAG, you can start here.
1. Open Google Colab
Create a new notebook:
Then run the following cells from top to bottom.
2. Install nlp4j-local-search
First, install the search library.
!pip install nlp4j-local-search==0.8.0.0
Then install the optional embedding package.
!pip install nlp4j-local-search-embedding
That's all we need to install.
3. Import SearchEngine
Run the next cell:
from nlp4j_local_search import SearchEngine
4. Prepare Some Documents
Let's use a few simple English sentences.
documents = [
{"id": "1", "body": "Kyoto was the ancient capital of Japan."},
{"id": "2", "body": "Tokyo is the largest city in Japan."},
{"id": "3", "body": "Nara has many historic temples and shrines."},
{"id": "4", "body": "Osaka is famous for its food culture."},
{"id": "5", "body": "Hokkaido is known for its vast natural landscapes."},
]
You can check the data:
documents
There are no vectors here yet.
These are just ordinary Python strings.
5. Create a Search Engine
Now let's create the search engine.
engine = SearchEngine("en", embedding=True)
The important part is:
embedding=True
This enables automatic text embedding.
By default, nlp4j-local-search-embedding uses:
intfloat/multilingual-e5-large
The model generates 1024-dimensional embeddings.
On the first run, the model (approximately 2.2 GB) will be downloaded from Hugging Face, so this step can take a little time.
6. Add One Document
Let's add just one document first.
engine.add("1", "Kyoto was the ancient capital of Japan.")
That's it.
You don't need to manually write something like:
vector = model.encode(text)
nlp4j-local-search handles the embedding for you.
7. Add More Documents
Run these cells one by one.
engine.add("2", "Tokyo is the largest city in Japan.")
engine.add("3", "Nara has many historic temples and shrines.")
engine.add("4", "Osaka is famous for its food culture.")
engine.add("5", "Hokkaido is known for its vast natural landscapes.")
Now commit the documents:
engine.commit()
Check the number of documents:
engine.count()
You should get:
5
Our vector search index is ready.
8. Try Vector Search
Now let's search for:
old Japanese capital
Run:
results = engine.search_semantic("old Japanese capital", limit=3)
Then:
for r in results:
print(r.id, r.body, r.score)
You should see semantically related documents near the top, such as:
Kyoto was the ancient capital of Japan.
Notice that the query was:
old Japanese capital
while the document says:
ancient capital of Japan
Vector search is not simply looking for exact matching words. It searches by semantic similarity.
9. Try Different Queries
This is where Colab is useful.
Change the query and immediately see what happens.
Try:
results = engine.search_semantic("historic religious buildings", limit=3)
for r in results:
print(r.id, r.body, r.score)
Now try:
results = engine.search_semantic("a very large city", limit=3)
for r in results:
print(r.id, r.body, r.score)
Or:
results = engine.search_semantic("somewhere with lots of nature", limit=3)
for r in results:
print(r.id, r.body, r.score)
You can keep changing the query and experimenting.
10. Keyword Search Is Also Available
The same search engine also supports traditional keyword search.
results = engine.search("Kyoto", limit=5)
for r in results:
print(r.id, r.body, r.score)
So:
engine.search("Kyoto")
performs keyword search, while:
engine.search_semantic("old Japanese capital")
performs semantic vector search.
The APIs are intentionally separated so that it is easy to see which type of search is being used.
11. Combine Vector Search with a Filter
You can also restrict the documents before performing vector search.
For example:
results = engine.search_semantic(
"city",
limit=5,
filter_query="id:1 OR id:2",
)
Then:
for r in results:
print(r.id, r.body, r.score)
The semantic search is now restricted to documents matching:
id:1 OR id:2
The filter uses Lucene Query Syntax.
This becomes useful with real datasets where you may want to filter by things such as category, product, date, manufacturer, or document type before performing semantic search.
12. What Is Running Behind This?
The Python API is deliberately simple, but Apache Lucene 10.x is running behind it.
The architecture looks roughly like this:
Google Colab
|
Python
|
nlp4j-local-search
|
+---- Embedding
| |
| +---- multilingual-e5-large
|
+---- Apache Lucene 10.x
|
+---- Keyword Search
+---- Vector Search
There is no separate Lucene server.
There is also no Elasticsearch, OpenSearch, or dedicated vector database server to configure and operate for this experiment.
13. A Small Building Block for RAG
Vector search is one of the fundamental technologies commonly used for RAG (Retrieval-Augmented Generation).
A very simplified RAG pipeline looks like this:
Question
↓
Embedding
↓
Vector Search
↓
Relevant Documents
↓
LLM
↓
Answer
If you are learning about RAG, you don't necessarily need to start by building the whole system.
You can first experiment with the retrieval part:
engine.search_semantic("my question")
and see how semantic retrieval actually behaves.
14. Create → Search → Discard
Another useful feature for small experiments is that nlp4j-local-search can work entirely in memory.
In this example, we simply created:
engine = SearchEngine("en", embedding=True)
added some data, searched it, and used the results.
This enables a very simple workflow:
Create an index
↓
Add temporary data
↓
Search
↓
Discard the index
In other words:
Create → Search → Discard
You don't always need permanent search infrastructure.
For an experiment, a temporary dataset, or an AI task that only needs an index during processing, creating an in-memory search index and throwing it away afterward can be much simpler.
This also fits Google Colab very well.
When the Colab runtime disappears, your temporary in-memory search environment disappears with it.
15. Close the Search Engine
When you are finished:
engine.close()
Done.
The Whole Example Is Actually Very Small
After experimenting one cell at a time, you can see that the essential code is only this:
from nlp4j_local_search import SearchEngine
with SearchEngine("en", embedding=True) as engine:
engine.add("1", "Kyoto was the ancient capital of Japan.")
engine.add("2", "Tokyo is the largest city in Japan.")
engine.add("3", "Nara has many historic temples and shrines.")
engine.commit()
for r in engine.search_semantic("old Japanese capital", limit=3):
print(r.body)
There is no explicit vector in the code.
There is no vector database configuration.
There is no search server configuration.
There is no explicit embedding code.
But it is performing semantic vector search.
Summary
If you just want to experiment with vector search, Google Colab + nlp4j-local-search provides a very small starting point.
Start with:
!pip install nlp4j-local-search==0.8.0.0
!pip install nlp4j-local-search-embedding
Then:
engine = SearchEngine("en", embedding=True)
engine.add("1", "Kyoto was the ancient capital of Japan.")
engine.commit()
engine.search_semantic("old Japanese capital")
That's enough to start experimenting.
No search server to build.
No vector database server to manage.
No Docker environment to prepare.
Just open Google Colab and try vector search one cell at a time.
Links
Google Colab:
nlp4j-local-search 0.8.0.0:
GitHub: