Implement an In-Memory Query Engine
ValonSoftware Engineer · Technical ScreenLast updated
Design and implement an in-memory query engine capable of ingesting records and executing structured queries with comparison, membership, and logical operators.
Problem Statement
You are tasked with building a lightweight, in-memory query engine. The engine stores structured records (dictionaries) and supports filtering rows using a query language that supports comparison operators, membership checks, and nested logical combinations (AND, OR, NOT).
Implement the InMemoryQueryEngine class with the following methods:
class InMemoryQueryEngine:
def __init__(self):
pass
def insert(self, record: dict) -> None:
"""Inserts a single dictionary record into the engine."""
pass
def query(self, condition: dict) -> list[dict]:
"""Returns all inserted records that satisfy the given filter condition."""
pass
Query Syntax
A condition dictionary can either be a field predicate or a logical predicate:
-
Field Predicate:
{ "field_name": { "": } }Supported operators:"$eq": Equal to value."$gt": Strictly greater than value."$lt": Strictly less than value."$in": Value must be an element in the provided list."$nin": Value must not be an element in the provided list.
-
Logical Predicate:
{ "$and": [condition1, condition2, ...] }: All child conditions must beTrue.{ "$or": [condition1, condition2, ...] }: At least one child condition must beTrue.{ "$not": condition }: Inverts the result of the child condition.
If condition is an empty dictionary {}, return all records.
Field Handling & Types
- Record keys are strings. Values may be integers, floats, strings, or
None. - If a field referenced in a comparison does not exist in a record, treat its value as
None. - For
"$gt"and"$lt", if the record value isNoneor if types are incomparable (e.g., comparing an integer to a string), the condition evaluates toFalse. - Preserved order: Return records in the order they were inserted.
Examples
Example 1
engine = InMemoryQueryEngine()
engine.insert({"id": 1, "name": "Alice", "age": 30, "status": "ACTIVE"})
engine.insert({"id": 2, "name": "Bob", "age": 24, "status": "PENDING"})
engine.insert({"id": 3, "name": "Charlie", "age": 35, "status": "ACTIVE"})
q = {
"$and": [
{"status": {"$eq": "ACTIVE"}},
{"age": {"$gt": 25}}
]
}
print(engine.query(q))
# Output:
# [
# {"id": 1, "name": "Alice", "age": 30, "status": "ACTIVE"},
# {"id": 3, "name": "Charlie", "age": 35, "status": "ACTIVE"}
# ]
Example 2
q2 = {
"$or": [
{"status": {"$in": ["PENDING", "ARCHIVED"]}},
{"name": {"$eq": "Charlie"}}
]
}
print(engine.query(q2))
# Output:
# [
# {"id": 2, "name": "Bob", "age": 24, "status": "PENDING"},
# {"id": 3, "name": "Charlie", "age": 35, "status": "ACTIVE"}
# ]
Constraints
- Up to
10,000records inserted. - Up to
5,000query calls. - Maximum depth of nested logical operators is
10. - Field names and string values contain alphanumeric characters only.
Hints
Hint 1
Model the filter evaluation recursively by distinguishing between logical keys ('$and', '$or', '$not') and record field names.
Hint 2
For membership operators like '$in' and '$nin', convert the query target list to a hash set for O(1) lookups if evaluating across many rows.
Hint 3
Ensure safe comparisons by checking that both types match and neither is None before evaluating relative orderings ('$gt', '$lt').
Follow-up questions
- How would you add indexing (e.g., hash maps or B-trees) to avoid scanning every record on every query?
- How would you extend this engine to support projection (selecting a subset of fields) and sorting (`ORDER BY`)?
- If updates and deletes need to be supported concurrently with queries, how would you ensure thread-safety?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.