Laravel · Livewire · Nested Boolean Expressions · Multi-Source Search · AND / OR / NOT
Application-Level Search Architecture Built Under Elasticsearch Deployment Constraints
Project positioning
This project was developed as an advanced search subsystem in Laravel when the project constraints did not allow deployment of Elasticsearch in the target environment.
Rather than reducing the requirement to a simple SQL
LIKEsearch, the implementation introduced a custom Boolean query interpreter capable of:
- searching across multiple semantic data sources,
- evaluating independent search blocks,
- combining result sets with
AND,OR, andNOT,- supporting grouped / nested Boolean expressions,
- normalizing heterogeneous data sources into a common result-ID space,
- and returning the final result set through Laravel / Livewire with pagination.
The strongest portfolio framing is:
A custom application-level Boolean search engine implemented in Laravel/Livewire, with multi-source query resolution, nested Boolean expressions, and set-based result evaluation.
It should not be described merely as:
“an advanced search form.”
The important engineering work was the query interpretation and evaluation layer behind the interface.
Classification
- Project Type: Search Engine / Query Interpreter
- Framework: Laravel
- Reactive UI: Livewire
- Primary Problem: Advanced multi-source search without Elasticsearch
- Query Model: Nested Boolean expressions
- Supported Operators:
AND,OR,NOT - Evaluation Model: Set algebra over normalized result IDs
- Data Sources visible in the historical implementation:
- All Data
- Authors
- Highlights
- Keywords
- Learning Point
- Pagination: Livewire pagination
- Deployment Constraint: Elasticsearch not available for online deployment due to employer/customer constraints around data protection/infrastructure/budget
- Portfolio Relevance: Very High
- Suggested CV Relevance: Tier A — Algorithms, Search, Query Parsing, Laravel, Livewire, Relational Data Modeling
Website Card
Title:
Custom Boolean Query Parser & Set-Based Search Engine
Subtitle:
Laravel · Livewire · Nested Expressions · Multi-Source Search
One-line Description:
Built a custom Laravel/Livewire search engine that interprets nested Boolean expressions across multiple data sources and combines normalized result sets using AND, OR, and NOT without relying on Elasticsearch.
Categories:
- Laravel
- Livewire
- Search Engine
- Query Parser
- Boolean Logic
- Algorithms
- Relational Search
- Set Algebra
- Advanced Search
Concept Tags:Laravel · Livewire · AND · OR · NOT · Nested Query · Query Parser · Set Intersection · Set Union · Set Difference
Executive Summary
The project required more than a normal keyword search.
Users needed to construct searches such as:
("gastric outlet obstruction" OR GOO) AND diabetes
and also build advanced multi-row queries where each row could search a different logical source such as:
Authors
Highlights
Keywords
Learning Point
All Data
Those individual query blocks could then be connected with Boolean operators:
AND
OR
NOT
The result was effectively a small search language.
Conceptually:
Search Term / Search Block
↓
Source Resolver
↓
Result ID Set
↓
Boolean Operator
↓
Combined Result Set
↓
Final Search Results
Why the Project Was Needed
A basic database search usually handles a pattern such as:
WHERE caption LIKE '%diabetes%'
The requirement here was substantially more complex.
Users needed to ask questions such as:
Author = Smith
AND
Keyword = Diabetes
NOT
Highlight = Surgery
or:
("gastric outlet obstruction" OR GOO)
AND
diabetes
This means the search engine needed to understand:
- search field,
- search term,
- Boolean operator,
- grouping,
- nesting,
- and result-set combination.
Infrastructure Constraint
The project could not depend on an online Elasticsearch deployment.
The relevant project constraint was not a lack of awareness of Elasticsearch.
Instead, the application had to operate under restrictions related to:
- data protection,
- customer infrastructure,
- deployment policy,
- and/or available project budget.
Therefore the search logic was implemented inside the Laravel application stack.
A precise portfolio description is:
A custom application-level search engine was implemented because Elasticsearch could not be deployed in the target environment.
Core Idea
The central design decision was to convert heterogeneous search results into a common ID space.
Each search source produced a set of matching prototype/result IDs.
Example:
Authors
↓
Matching Author Records
↓
Author ↔ Prototype Relation
↓
Prototype IDs
Similarly:
Keywords
↓
Matching Keyword Records
↓
Keyword ↔ Prototype Relation
↓
Prototype IDs
Once all sources returned the same kind of identifier, Boolean logic could operate on sets instead of on unrelated tables.
Normalization Layer
Conceptually:
Authors ───────────┐
Highlights ────────┤
Keywords ──────────┤
Learning Points ───┤
All Data ──────────┘
↓
Normalized Result IDs
↓
Boolean Evaluation
This normalization layer is one of the strongest parts of the design.
Search Sources
The historical screenshots and code show multiple searchable sources.
1. All Data
The implementation searches directly against the main prototype/entity table.
The screenshot shows logic conceptually equivalent to:
AllPrototype::where(
'caption',
'LIKE',
'%' . $searching . '%'
)
->pluck('id')
->toArray();
This produces matching top-level record IDs directly.
2. Authors
The code searches an author-related table first:
Author Search
↓
Matching Author IDs
↓
Author-to-Prototype Relation
↓
Prototype IDs
The screenshot shows the use of an intermediate relation table similar to:
AuthorsPrototypes
This demonstrates that the search engine had to traverse relational data rather than only search one flat table.
3. Highlights
The same pattern appears for highlighted / important content:
Highlight Search
↓
Highlight IDs
↓
Highlight-to-Prototype Relation
↓
Prototype IDs
4. Keywords
Keywords are resolved through another relation:
Keyword Search
↓
Keyword IDs
↓
Keyword-to-Prototype Relation
↓
Prototype IDs
5. Learning Point
Learning points are also searched independently and then normalized back to the shared result entity:
Learning Point
↓
Learning Point IDs
↓
LearningPoint ↔ Prototype Relation
↓
Prototype IDs
Shared Result Space
After source-specific searching, every query block becomes:
Set<int> PrototypeIds
This is what makes generic Boolean evaluation possible.
Boolean Operators
The historical implementation visibly maps Boolean operators to array/set operations.
AND
The code uses:
array_intersect(...)
Mathematically:
A AND B
=
A ∩ B
Meaning:
keep only result IDs that exist in both sets.
OR
The code uses:
array_unique(array_merge(...))
Mathematically:
A OR B
=
A ∪ B
Meaning:
include result IDs that exist in either set.
NOT
The code uses:
array_diff(...)
Conceptually:
A NOT B
=
A − B
Meaning:
keep IDs from the first set except those that occur in the second.
Why Set Algebra Was a Good Fit
Once each search source was normalized to IDs, the logical problem became independent of the database schema.
The engine no longer needed to know:
"This came from Authors"
or:
"This came from Keywords"
during final Boolean combination.
It only needed:
Set A
Set B
Operator
This simplifies the logical model significantly.
Query Evaluation Model
Conceptually:
Query A
↓
Set A
Query B
↓
Set B
Operator
↓
A ∩ B
or
A ∪ B
or
A − B
Nested Boolean Expressions
The project supported nested search expressions.
This means a simple search could become a component inside a larger search.
Example:
Q1 = Author contains "Smith"
Q2 = Keyword contains "Diabetes"
Q3 = Highlight contains "Surgery"
First:
Q1 AND Q2
produces:
R1
Then:
R1 NOT Q3
produces:
(Author = Smith AND Keyword = Diabetes)
NOT
Highlight = Surgery
This result could then participate in another expression.
Recursive Search Concept
Conceptually:
Expression
├── Left Expression
├── Boolean Operator
└── Right Expression
This is structurally recursive.
A nested query is therefore not just a string.
It can be modeled as a tree.
Query Tree Example
Input:
(A OR B) AND C
Tree:
AND
/ \
OR C
/ \
A B
Evaluation proceeds bottom-up.
Larger Example
(
(Author = Smith OR Author = Jones)
AND
Keyword = Diabetes
)
NOT
Highlight = Surgery
Conceptual tree:
NOT
/ \
AND Highlight=Surgery
/ \
OR Keyword=Diabetes
/ \
Smith Jones
UI — Simple Search
The historical UI includes a top-level free-text search.
The example placeholder visible in the screenshot demonstrates Boolean syntax:
("gastric outlet obstruction" OR GOO) AND diabetes
This immediately communicates that the search engine supports expressions rather than only literal keyword matching.
UI — Advanced Search
The advanced form contains several query rows.
Each row provides:
- a data source selector,
- a search term input,
- and a Boolean operator connection.
This allows the user to compose search logic visually.
Search Field Selector
The source selector visibly contains options such as:
All Data
Authors
Highlights
Keywords
Learning Point
This means the user can decide the semantic context of each term.
Boolean Operator Selector
The operator selector visibly contains:
OR
AND
NOT
This provides explicit control over how adjacent search blocks interact.
Visual Query Builder
The advanced search screen is essentially a visual query builder.
Instead of writing:
(author:"Smith" AND keyword:"diabetes")
the user can construct the same intent through rows and selectors.
This reduces the learning curve.
Dual Interaction Model
The project therefore supported two styles:
Textual Expression
("gastric outlet obstruction" OR GOO) AND diabetes
Visual Builder
[Authors] [Smith] AND
[Keywords] [Diabetes] NOT
[Highlights] [Surgery]
Both represent Boolean search logic.
Livewire Component
The code screenshot shows:
class SearchAdvanced extends Component
and:
use WithPagination;
This confirms that the advanced search was implemented as a Livewire component.
Livewire Responsibilities
The component handled:
- user search inputs,
- source selectors,
- operators,
- result calculation,
- pagination,
- render lifecycle.
Historically, much of the query logic was also contained inside the component itself.
Historical Parser Logic
The screenshot shows the implementation inspecting the input string for operators such as:
AND
OR
NOT
It also checks whether the first character is an opening parenthesis:
(
This demonstrates that the implementation attempted to interpret expression structure rather than treat the entire string as plain text.
String Parsing
The historical implementation contains logic similar to:
Normalize Case
↓
Search for " AND "
↓
Search for " OR "
↓
Search for " NOT "
↓
Inspect Parentheses
↓
Split / Transform Expression
This is effectively a lightweight parser.
Query Language
The project implemented a small domain-specific search language.
Its conceptual grammar can be summarized as:
Expression
= Term
| "(" Expression ")"
| Expression AND Expression
| Expression OR Expression
| Expression NOT Expression
The historical parser implementation was imperative rather than grammar-driven, but the behavior is close to this conceptual language.
Query Interpreter
The overall engine can be described as:
Input Expression
↓
Interpretation
↓
Source-Specific Search
↓
Normalized IDs
↓
Boolean Evaluation
↓
Final Records
Search Engine vs Query Builder
This project contains both:
Query Builder
The UI where users define search blocks.
Query Engine
The backend that evaluates those blocks.
These should be treated as separate architectural concerns.
Historical Implementation Evidence
The screenshots show:
SearchAdvanced extends ComponentWithPagination- request-driven field selection
- operator selection
- string inspection for
AND,OR,NOT - source-specific Eloquent queries
- ID extraction through
pluck array_intersectarray_mergearray_uniquearray_diff- pagination of the final result model.
This provides strong evidence that the project implemented a custom evaluator rather than only building a search UI.
Source Resolution
A clean conceptual abstraction is:
SearchSourceResolver
Input:
source = "Authors"
term = "Smith"
Output:
Set<PrototypeId>
Generic Resolver Contract
Modern V2 interface:
SearchSource
search(string term): Set<ResultId>
Potential implementations:
AllDataSearchSource
AuthorSearchSource
HighlightSearchSource
KeywordSearchSource
LearningPointSearchSource
Boolean Evaluator
Then a separate evaluator only understands:
Set
Operator
Set
It does not care where the sets came from.
This separation improves maintainability.
Historical Coupling
In the historical component, parsing, source resolution, Boolean evaluation, and final rendering are heavily coupled.
The screenshots show many counters and large imperative branches.
This is valuable historical evidence but also clearly identifies the modernization opportunity.
Historical Complexity
The screenshot shows line numbers exceeding:
1700
inside the search implementation.
This indicates that a large amount of search behavior had accumulated in one component.
The historical system worked, but the code structure could be significantly improved.
Modern V2 Architecture
A much stronger implementation would use four main stages:
Tokenizer
↓
Parser
↓
AST
↓
Evaluator
with source resolution separated from expression parsing.
Full Modern Pipeline
User Input
↓
Tokenizer
↓
Parser
↓
Abstract Syntax Tree
↓
Search Source Resolver
↓
Set Evaluator
↓
Result IDs
↓
Repository / Query
↓
Pagination
↓
Livewire UI
Tokenizer
The tokenizer converts raw input into tokens.
Example input:
("gastric outlet obstruction" OR GOO) AND diabetes
Possible tokens:
LPAREN
PHRASE("gastric outlet obstruction")
OR
WORD(GOO)
RPAREN
AND
WORD(diabetes)
Token Types
A modern tokenizer could support:
WORD
PHRASE
LPAREN
RPAREN
AND
OR
NOT
FIELD
EOF
Parser
The parser transforms the token stream into an expression tree.
Example:
(A OR B) AND C
becomes:
AndNode
├── OrNode
│ ├── TermNode(A)
│ └── TermNode(B)
└── TermNode(C)
Abstract Syntax Tree
Example interfaces:
ExpressionNode
├── TermNode
├── AndNode
├── OrNode
└── NotNode
This makes nested expressions natural.
Evaluator
The evaluator recursively evaluates the AST.
Pseudo logic:
evaluate(TermNode)
→ source.search(term)
evaluate(AndNode)
→ intersection(left, right)
evaluate(OrNode)
→ union(left, right)
evaluate(NotNode)
→ difference(left, right)
Operator Precedence
A formal parser can define precedence explicitly.
For example:
Parentheses
NOT
AND
OR
or whatever precedence the product specification requires.
The historical implementation should only be documented with the exact behavior recoverable from source code; precedence should not be assumed.
Why AST Is Better
With an AST:
(A OR B) AND (C NOT D)
does not require special-case logic for every nesting depth.
The parser handles structure once.
The evaluator handles node types generically.
Unlimited Nesting Conceptually
The same recursive model can support:
(
(A OR B)
AND
(C NOT D)
)
OR
(
E AND
(
F OR G
)
)
without multiplying if/else branches.
Parser Testing
A dedicated parser can be tested independently from the database.
Examples:
A AND B
A OR B
A NOT B
(A OR B) AND C
A AND (B OR C)
Expected ASTs can be asserted.
Search Source Testing
Each search source can be tested separately.
Example:
AuthorSearchSource("Smith")
should return the expected normalized IDs.
Evaluator Testing
The evaluator can use in-memory sets.
Example:
A = {1,2,3}
B = {2,3,4}
AND:
{2,3}
OR:
{1,2,3,4}
NOT:
{1}
This isolates the Boolean logic completely from Laravel/Eloquent.
Query Planning
A stronger V2 could optimize evaluation order.
Example:
LargeSet AND SmallSet
can often be evaluated more efficiently by resolving the more selective search first.
Cost Awareness
Potential source costs differ.
For example:
All Data LIKE search
Author relation lookup
Keyword relation lookup
may have different costs.
A future query planner could estimate selectivity.
Database-Level Optimization
The historical implementation evaluates many operations in PHP arrays.
For moderate result sets this is straightforward.
For large datasets, a modern V2 could push some Boolean operations closer to the database.
Options include:
- subqueries,
- joins,
whereExists,- temporary tables,
- CTEs,
- indexed pivot tables.
Why Application-Level Set Evaluation Still Has Value
Application-level evaluation is attractive when:
- multiple search sources have different schemas,
- result counts are manageable,
- deployment simplicity matters,
- search logic changes frequently.
It is also easier to reason about than dynamically generating deeply nested SQL.
Hybrid Strategy
A robust V2 can use:
Database
→ Resolve Individual Query Blocks
Application
→ Combine Result Sets
This preserves the original design idea while improving structure.
Result IDs vs Full Models
The historical implementation wisely works with IDs during Boolean evaluation.
This is more memory-efficient than repeatedly merging full Eloquent model objects.
Conceptually:
Search
→ IDs
→ Boolean Logic
→ Final IDs
→ Fetch Final Models
This is a good pattern.
Pagination
The final screenshot shows the final result IDs passed back to the result model and paginated.
Conceptually:
Final Result IDs
↓
whereIn(id, ...)
↓
paginate(...)
This separates logical search calculation from final record rendering.
Pagination Considerations
A modern implementation should preserve result ordering explicitly.
whereIn alone does not guarantee the original logical order.
If ranking matters, ordering must be defined separately.
Ranking
The historical evidence shows Boolean filtering, not a relevance-ranking engine.
Do not claim:
- BM25,
- TF-IDF,
- relevance scoring,
- semantic vector search,
unless implemented separately.
Search Semantics
This project is fundamentally a Boolean retrieval engine, not a ranking search engine.
That distinction is technically important.
Boolean Retrieval Model
In information retrieval terminology:
Document either matches or does not match
according to Boolean criteria.
This differs from ranked retrieval where documents receive relevance scores.
Exact Phrase Support
The example UI suggests quoted phrases such as:
"gastric outlet obstruction"
The screenshots demonstrate phrase-like syntax in the search placeholder.
The exact historical phrase-parsing behavior should be described only from verified code behavior.
Parentheses
The parser code visibly inspects parentheses.
This confirms that grouping was part of the parsing concern.
Exact nesting depth/edge-case behavior should be verified against source if needed.
Error Handling — Modern V2
A formal parser should produce useful validation errors.
Examples:
Unexpected AND
Missing closing parenthesis
Empty expression
Unknown field
Example Validation
Input:
A AND
Response:
Expected expression after AND
Query AST Serialization
A modern system could serialize visual-builder queries as JSON.
Example:
{
"type": "AND",
"left": {
"type": "TERM",
"field": "authors",
"value": "Smith"
},
"right": {
"type": "TERM",
"field": "keywords",
"value": "Diabetes"
}
}
This avoids reparsing UI-generated queries from strings.
Visual Builder + Text Query Interoperability
A strong V2 could support both:
Text Query
and:
Visual Query Builder
by converting both into the same AST.
Architecture
Text Query ───────┐
↓
Tokenizer
↓
Parser
↓
Visual Builder ─────────→ AST
↓
Query Evaluator
↓
SearchSourceResolver
↓
Result ID Set
↓
Pagination
Field-Aware Search
Each term may contain both:
Field
Value
Example:
field = Authors
value = Smith
This is different from a global free-text search.
Domain Search Adapters
A clean V2 could define:
interface SearchAdapter
{
public function search(string $term): array;
}
Implementations:
AuthorSearchAdapter
KeywordSearchAdapter
HighlightSearchAdapter
LearningPointSearchAdapter
AllDataSearchAdapter
Repository Layer
The search adapters should delegate database access to repositories/query objects where appropriate.
This keeps Eloquent concerns separate from expression evaluation.
Example V2 Service Graph
SearchController / Livewire Component
↓
SearchApplicationService
↓
Parser
↓
AST
↓
Evaluator
↓
SourceRegistry
↓
Search Adapters
↓
Repositories
↓
Database
Source Registry
Instead of repeated if/elseif:
if source == 1
elseif source == 2
elseif source == 3
use:
SourceRegistry
Example:
all_data → AllDataSearchAdapter
authors → AuthorSearchAdapter
highlights → HighlightSearchAdapter
keywords → KeywordSearchAdapter
learning_point → LearningPointSearchAdapter
Benefits of Source Registry
- easier extension,
- less branching,
- independent testing,
- clearer dependencies.
Adding a New Search Domain
Historical style may require editing a large branch.
V2:
Create Adapter
Register Adapter
No parser changes required.
Query Objects
Another strong option is to model each search block as:
SearchClause
├── field
├── term
└── options
and Boolean composition as expression nodes.
SQL Injection Boundary
Because the engine interprets user expressions, it must never concatenate user values into raw SQL unsafely.
The historical screenshots show Eloquent builder usage such as:
where(..., 'LIKE', ...)
which is preferable to directly concatenating raw SQL strings.
Wildcard Search
The code uses patterns similar to:
%term%
This supports substring matching.
Performance Trade-Off of %term%
Leading wildcards typically prevent normal B-tree indexes from being fully effective.
This is an important limitation of SQL-based text search.
A future implementation could use:
- database full-text search,
- trigram indexes,
- PostgreSQL
pg_trgm, - dedicated search engine if deployment constraints change.
PostgreSQL Modernization Option
If Elasticsearch remains unavailable, PostgreSQL can significantly strengthen the design.
Potential tools:
GIN indexes
pg_trgm
tsvector
tsquery
This may reduce the need for broad %LIKE% scans.
Why Elasticsearch Would Still Be Different
A dedicated search engine provides:
- inverted indexes,
- scoring,
- analyzers,
- tokenization,
- fuzzy search,
- scalable text retrieval.
The custom system was designed to satisfy Boolean search requirements under a constrained deployment model, not to reproduce every Elasticsearch capability.
Security / Data Protection Context
The search architecture is a good example of a technical decision shaped by deployment constraints.
A technically ideal service is not always deployable.
The engineering task becomes:
Required Functionality
+
Available Infrastructure
+
Data Constraints
=
Practical Architecture
Product Value
The project gave users advanced retrieval capability without requiring dedicated search infrastructure.
The core value was:
Multi-Domain Search
+
Nested Boolean Logic
+
Laravel-Native Deployment
Historical UI Evidence
The screenshots show:
Simple search bar
with a Boolean-expression example.
Advanced Search
with multiple rows.
Source selector
with:
All Data
Authors
Highlights
Keywords
Learning Point
Boolean selector
with:
AND
OR
NOT
Laravel / Livewire source code
showing the custom parser/evaluator.
This is unusually strong portfolio evidence because both UX and implementation are documented.
Suggested Screenshot Captions
Screenshot 1 — Multi-Source Query Builder
Advanced search interface allowing each search clause to target a different semantic source such as authors, highlights, keywords, learning points, or all data.
Screenshot 2 — Boolean Operators
Visual Boolean composition using AND, OR, and NOT between independent search clauses.
Screenshot 3 — Parser Logic
Historical Livewire search component parsing textual Boolean expressions and grouping syntax.
Screenshot 4 — Source Resolution
Source-specific Eloquent queries normalized into common result IDs before Boolean evaluation.
Screenshot 5 — Set-Based Evaluation
Application-layer Boolean evaluator combining result sets through difference, intersection, and union operations.
Historical vs Modern Boundary
Confirmed Historical Capabilities
- Laravel implementation.
- Livewire component.
WithPagination.- free-text advanced search.
- multi-row advanced search UI.
- source selection.
- sources visible in screenshots:
- All Data,
- Authors,
- Highlights,
- Keywords,
- Learning Point.
- Boolean operators:
- AND,
- OR,
- NOT.
- inspection/parsing of textual Boolean operators.
- parentheses-related parsing logic.
- source-specific relational searches.
- normalization to common result IDs.
array_intersectfor AND.array_unique(array_merge())for OR.array_difffor NOT.- final result filtering and pagination.
- custom search engine used instead of Elasticsearch due to project deployment constraints.
Modern V2 Recommendations
- tokenizer,
- formal parser,
- AST,
- precedence rules,
- source registry,
- source adapters,
- dedicated evaluator,
- query validation,
- AST serialization,
- PostgreSQL full-text/trigram indexing,
- parser/evaluator unit tests.
What Not to Overclaim
Do not describe the historical project as:
- Elasticsearch replacement with equivalent performance,
- semantic search,
- AI search,
- vector search,
- full-text relevance engine,
- BM25 search,
- natural-language search engine,
unless those features existed separately.
The precise claim is:
Custom nested Boolean retrieval engine over relational data sources.
My Role
A strong and precise portfolio description:
I developed a custom Boolean search engine in Laravel/Livewire when Elasticsearch could not be deployed in the target environment. The system resolved queries across multiple data domains—including authors, highlights, keywords, learning points, and general content—normalized them into common result-ID sets, and evaluated nested AND/OR/NOT expressions through set operations before returning paginated results.
Engineering Highlights
- Laravel.
- Livewire.
- Advanced search UI.
- Custom Boolean expression parsing.
- Multi-source search.
- Relational source resolution.
- Result normalization.
- Set-based evaluation.
- Nested search expressions.
- Parentheses/grouping logic.
- Pagination.
- Search infrastructure implemented without Elasticsearch.
- Application-level query interpretation.
Algorithmic Highlights
The project combines several computer-science concepts:
Parsing
+
Boolean Algebra
+
Set Theory
+
Relational Data Traversal
+
Query Evaluation
This is why it should be treated as an algorithmic project, not merely a form-heavy Laravel page.
Set Theory Mapping
AND → Intersection
OR → Union
NOT → Difference
This mapping is one of the clearest ways to explain the engine in technical interviews.
Career Evidence
This project demonstrates experience with:
- Search Architecture
- Laravel
- Livewire
- Boolean Logic
- Query Parsing
- Set Algebra
- Relational Data Modeling
- Algorithmic Problem Solving
- Infrastructure-Constrained Design
- Legacy-to-Clean-Architecture Refactoring
CV Relevance
Tier A — Search / Algorithms / Backend Engineering
The strongest technical story is:
NO ELASTICSEARCH
↓
CUSTOM QUERY LANGUAGE
↓
MULTI-SOURCE RESOLUTION
↓
NORMALIZED RESULT SETS
↓
BOOLEAN SET EVALUATION
↓
PAGINATED SEARCH RESULTS
Interview Story
Situation
The application needed advanced search capabilities across several different kinds of data.
A dedicated Elasticsearch deployment was not available in the target environment because of project infrastructure/data-protection/budget constraints.
Task
The search experience still needed to support:
- multiple search domains,
- Boolean operators,
- grouped expressions,
- and nested combinations.
Action
I implemented the search engine inside Laravel/Livewire.
Each search clause was resolved against its specific data source.
Those heterogeneous results were normalized into a common set of top-level record IDs.
I then evaluated the Boolean logic in the application layer using set operations:
AND → intersection
OR → union
NOT → difference
The search interface supported both free-text Boolean syntax and a visual advanced-search builder.
Result
The application gained a flexible advanced search capability without requiring a separate search infrastructure service.
Technical Interview Explanation — Short Version
“The difficult part wasn't writing
LIKEqueries. Each search field represented a different relational domain. I first resolved each clause into a common set of record IDs, then treated the Boolean expression as a set-algebra problem. AND became intersection, OR became union, and NOT became difference. That allowed nested search clauses to be combined independently of where each result originally came from.”
Technical Interview Explanation — Deep Version
“The historical implementation had both textual and visual Boolean search. Search clauses could target different domains, for example authors or keywords. The source-specific query first produced IDs for the main entity. Once normalized, the Boolean engine could combine these sets without caring about the original schema. The parser was implemented imperatively inside Livewire. If I rebuilt it today, I would separate tokenization, parsing, AST construction, source resolution, and evaluation so arbitrary nesting becomes recursive rather than branch-heavy.”
Suggested Website Full Description
Overview
The Custom Boolean Query Parser & Set-Based Search Engine was developed in Laravel and Livewire to provide advanced search without relying on an externally deployed Elasticsearch service.
Multi-Source Search
Users could search across several semantic domains, including:
- all data,
- authors,
- highlights,
- keywords,
- learning points.
Each domain used its own relational lookup strategy.
Result Normalization
Every search clause ultimately returned IDs belonging to the same top-level result entity.
This made search domains interoperable.
Boolean Evaluation
The normalized sets were combined using:
AND → Intersection
OR → Union
NOT → Difference
Nested Expressions
Users could combine small expressions into larger expressions, allowing complex nested Boolean queries.
Laravel / Livewire
Livewire handled the reactive advanced-search interface and paginated result lifecycle, while the search logic was implemented as custom application-level code.
Short Website Card Copy
Custom Boolean Query Parser & Search Engine
Built a Laravel/Livewire advanced search engine that resolves multiple relational search domains into common result sets and evaluates nested AND/OR/NOT expressions through set algebra without Elasticsearch.
Alternative One-Liners
Algorithm-oriented
Built a nested Boolean search engine that converts heterogeneous relational queries into normalized ID sets and evaluates them through set intersection, union, and difference.
Laravel-oriented
Developed a Laravel/Livewire advanced search subsystem with multi-field search, nested Boolean expressions, and application-level query evaluation.
Infrastructure-oriented
Implemented advanced Boolean search directly in Laravel when deployment constraints prevented use of Elasticsearch.
Architecture-oriented
Designed a custom query interpreter separating multi-source retrieval from Boolean result-set composition.
Suggested Website Slug
/projects/laravel-boolean-search-engine
Alternative:
/projects/custom-query-parser-search
Cover Direction
Title
Custom Boolean Search Engine
Subtitle
Nested Queries · AND / OR / NOT · Multi-Source Search
Supporting Line
Laravel · Livewire · Query Parser · Set Algebra
Visual Direction
A premium square technical cover should show:
- a central search input,
- nested parentheses,
- AND / OR / NOT nodes,
- multiple data-source blocks,
- branching query tree,
- result-set circles/intersections,
- Laravel / Livewire technical styling.
Primary visual story:
QUERY
→ PARSE
→ RESOLVE
→ COMBINE
→ RESULTS
Avoid making the cover look like:
- a generic website search bar,
- an AI chatbot,
- an Elasticsearch dashboard.
The visual message should be:
a custom Boolean query language and evaluation engine.
Modern V2 Architecture
Livewire UI
↓
Search Application Service
↓
Tokenizer
↓
Parser
↓
AST
↓
Evaluator
↓
Search Source Registry
↓
Adapters
↓
Repositories
↓
Database
Suggested Modern Classes
SearchTokenizer
SearchParser
ExpressionNode
TermNode
AndNode
OrNode
NotNode
SearchEvaluator
SearchSourceRegistry
SearchSource
Example Modern PHP Domain
Conceptual:
interface ExpressionNode {}
final class TermNode implements ExpressionNode
{
public function __construct(
public readonly string $field,
public readonly string $value,
) {}
}
final class AndNode implements ExpressionNode
{
public function __construct(
public readonly ExpressionNode $left,
public readonly ExpressionNode $right,
) {}
}
This is illustrative V2 architecture, not historical code.
Evaluator Concept
evaluate(TermNode $node)
=> sourceRegistry
->for($node->field)
->search($node->value);
evaluate(AndNode $node)
=> intersect(
evaluate($node->left),
evaluate($node->right)
);
Again, this is a modernization design.
Parser Grammar — V2
A possible grammar:
expression := orExpr
orExpr := andExpr ("OR" andExpr)*
andExpr := unaryExpr ("AND" unaryExpr)*
unaryExpr := "NOT" unaryExpr
| primary
primary := term
| "(" expression ")"
If the historical semantics of NOT are binary set-difference rather than unary negation, the grammar should be adapted accordingly.
Visual Builder AST
A visual advanced-search builder can skip tokenization entirely.
It can directly construct:
AST
from UI state.
This is preferable for reliability.
Persistence of Saved Searches
A modern V2 could store AST/query definitions as JSON.
Example use cases:
- saved searches,
- shared searches,
- reusable research filters.
This is a future enhancement, not a confirmed historical feature.
Query Versioning
If saved search syntax evolves, the JSON representation can include:
version
to support migrations.
Search Explain Mode
A future useful feature:
Explain Query
showing:
Author contains Smith
AND
Keyword contains Diabetes
NOT
Highlight contains Surgery
This helps users verify complex search logic.
Result Diagnostics
Another useful V2 capability:
Why did this result match?
For example:
Matched Author clause
Matched Keyword clause
Not excluded by Highlight clause
This is especially valuable in research-oriented applications.
Search Performance Telemetry
A modern system could measure:
Parse Time
Source Query Time
Set Evaluation Time
Final Fetch Time
This identifies the expensive stage.
Caching Strategy
Potential cacheable data:
- frequently repeated source queries,
- stable keyword mappings,
- normalized result-ID sets.
Cache invalidation must follow domain update behavior.
Large Result Sets
PHP array operations are simple and readable but can become memory-heavy for very large sets.
V2 alternatives include:
- database CTEs,
- temporary result tables,
- bitmap/set structures,
- search-engine infrastructure if later allowed.
Why the Historical Approach Still Matters
The project demonstrates a strong engineering principle:
The lack of an ideal infrastructure component does not remove the product requirement.
Instead, the problem was reframed into:
Search Source Resolution
+
Common ID Space
+
Set Algebra
and implemented within the available stack.
Final Portfolio Statement
The project should not be introduced as:
“a Laravel advanced search form.”
Its real engineering value is the query-processing architecture behind that form.
The strongest description is:
I built a custom Boolean search engine in Laravel/Livewire that parsed complex search expressions, resolved multiple relational data sources into normalized record-ID sets, and evaluated nested AND/OR/NOT logic through set operations when Elasticsearch could not be deployed in the target environment.
Conceptually:
USER QUERY
↓
BOOLEAN PARSING
↓
MULTI-SOURCE SEARCH
↓
NORMALIZED ID SETS
↓
AND / OR / NOT
↓
FINAL RESULTS