microsoft / microsoft/vscode-documentdb
Discuss: Querying with `{ field: null }` matches documents where the field is missing (not just BSON null)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 31
- Forks
- 22
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 21
Description
Problem
When a user queries for { title: null } using the Collection View filter or a Playground, the query returns documents where:
- The
titlefield is explicitly set to BSONnull(type 10), AND - Documents where the
titlefield does not exist at all
This is the documented behavior of the MongoDB API — { field: null } is an equality match that includes both BSON null values and missing fields. However, this is surprising and counter-intuitive for users who expect { title: null } to only find documents where title is explicitly null.
Reproduction
Given a collection movies with 300 documents, none of which have a title field set to null:
movie_db> db.movies.countDocuments()
300
movie_db> db.movies.find({ title: null }).count()
300
movie_db> db.movies.find({ title: "" }).count()
0
The user expected find({ title: null }) to return 0, but instead it returned 300 — because the MongoDB API treats null as matching both "field is null" and "field does not exist."
Root Cause
In the MongoDB API, the null equality filter has dual semantics:
| Query | Matches |
|---|---|
{ field: null } |
Documents where field is BSON null OR field does not exist |
{ field: { $type: 10 } } |
Only documents where field is BSON null (type 10) |
{ field: { $exists: false } } |
Only documents where field does not exist |
{ field: { $type: "null" } } |
Same as $type: 10 — only BSON null values |
JavaScript's native null maps directly to BSON type 10 during serialization, but the query semantics treat it as a broader match. There is no BSON Null() constructor in the BSON library (unlike MinKey(), MaxKey(), ObjectId(), etc.) — null is a native JSON/JS primitive, not a wrapped BSON type.
Ask
Investigate and choose a path to improve the user experience. Some options to consider:
-
Documentation / discoverability: Surface guidance in the extension (e.g., in the filter bar placeholder, tooltip, or query editor completions) explaining that
nullmatches missing fields, and suggest{ $type: 10 }for strict BSON null matching. -
Autocomplete enhancement: When the user types
nullin the filter bar, offer completions or a hint showing the three query variants (null,$type: 10,$exists: false). -
Query bar UX: Consider whether the filter bar could offer a structured way to express "is null" vs "field missing" vs "is null or missing" — for example through a dropdown or quick-action.
-
No change: Accept this as inherent MongoDB API behavior and rely on users learning the semantics.
The $type operator is already registered in the extension's query operators (packages/documentdb-constants/src/queryOperators.ts) with a snippet { $type: "${1:type}" }, so partial infrastructure exists. The question is how to make it more discoverable in the context of null queries.
cc @sajeetharan
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/documentdb-constants/src/queryOperators.ts, then trace the Collection View filter, Playground, and query-editor completion entry points mentioned in the issue. Compare the proposed documentation, autocomplete, and query-bar UX paths, and define done as a chosen approach that makes the distinction between null, missing fields, and BSON null discoverable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mongodb, typescript
- Domain
- database, developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100