Skip to content

Commit

Permalink
use concise correlated subquery syntax for relations with single colu…
Browse files Browse the repository at this point in the history
…mn mapping (#65)

This generates a simpler query plan when there is only one column mapping. Previously a `$lookup` looked like this:

```json
{
    "$lookup": {
        "from": "students",
        "let": {
            "v__id": "$_id"
        },
        "pipeline": [
            {
                "$match": { "$expr": {
                    "$eq": ["$$v__id", "$classId"]
                } }
            },
            {
                "$replaceWith": {
                    "student_name": { "$ifNull": ["$name", null] },
                },
            }
        ],
        "as": "students",
    },
},
```

After the change it looks like this:

```json
{
    "$lookup": {
        "from": "students",
        "localField": "_id",
        "foreignField": "classId",
        "pipeline": [
            {
                "$replaceWith": {
                    "student_name": { "$ifNull": ["$name", null] },
                },
            }
        ],
        "as": "students",
    },
},
```

Cases with multiple column mappings still use the first form.
  • Loading branch information
hallettj committed May 1, 2024
1 parent 58870c3 commit af3cd8b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 60 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This changelog documents the changes between release versions.
## [Unreleased]
- Enables logging events from the MongoDB driver by setting the `RUST_LOG` variable ([#67](https://github.com/hasura/ndc-mongodb/pull/67))
- To log all events set `RUST_LOG=mongodb::command=debug,mongodb::connection=debug,mongodb::server_selection=debug,mongodb::topology=debug`
- Relations with a single column mapping now use concise correlated subquery syntax in `$lookup` stage ([#65](https://github.com/hasura/ndc-mongodb/pull/65))

## [0.0.5] - 2024-04-26
- Fix incorrect order of results for query requests with more than 10 variable sets (#37)
Expand Down
118 changes: 58 additions & 60 deletions crates/mongodb-agent-common/src/query/relations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,50 @@ fn make_lookup_stage(
column_mapping: &ColumnMapping,
r#as: String,
lookup_pipeline: Pipeline,
) -> Result<Stage, MongoAgentError> {
// If we are mapping a single field in the source collection to a single field in the target
// collection then we can use the correlated subquery syntax.
if column_mapping.0.len() == 1 {
// Safe to unwrap because we just checked the hashmap size
let (source_selector, target_selector) = column_mapping.0.iter().next().unwrap();
single_column_mapping_lookup(
from,
source_selector,
target_selector,
r#as,
lookup_pipeline,
)
} else {
multiple_column_mapping_lookup(from, column_mapping, r#as, lookup_pipeline)
}
}

fn single_column_mapping_lookup(
from: String,
source_selector: &ColumnSelector,
target_selector: &ColumnSelector,
r#as: String,
lookup_pipeline: Pipeline,
) -> Result<Stage, MongoAgentError> {
Ok(Stage::Lookup {
from: Some(from),
local_field: Some(safe_column_selector(source_selector)?.to_string()),
foreign_field: Some(safe_column_selector(target_selector)?.to_string()),
r#let: None,
pipeline: if lookup_pipeline.is_empty() {
None
} else {
Some(lookup_pipeline)
},
r#as,
})
}

fn multiple_column_mapping_lookup(
from: String,
column_mapping: &ColumnMapping,
r#as: String,
lookup_pipeline: Pipeline,
) -> Result<Stage, MongoAgentError> {
let let_bindings: Document = column_mapping
.0
Expand Down Expand Up @@ -293,15 +337,9 @@ mod tests {
{
"$lookup": {
"from": "students",
"let": {
"v__id": "$_id"
},
"localField": "_id",
"foreignField": "classId",
"pipeline": [
{
"$match": { "$expr": {
"$eq": ["$$v__id", "$classId"]
} }
},
{
"$replaceWith": {
"student_name": { "$ifNull": ["$name", null] },
Expand Down Expand Up @@ -386,15 +424,9 @@ mod tests {
{
"$lookup": {
"from": "classes",
"let": {
"v_classId": "$classId"
},
"localField": "classId",
"foreignField": "_id",
"pipeline": [
{
"$match": { "$expr": {
"$eq": ["$$v_classId", "$_id"]
} }
},
{
"$replaceWith": {
"class_title": { "$ifNull": ["$title", null] },
Expand Down Expand Up @@ -602,31 +634,15 @@ mod tests {
{
"$lookup": {
"from": "students",
"let": {
"v__id": "$_id"
},
"localField": "_id",
"foreignField": "class_id",
"pipeline": [
{
"$match": {
"$expr": {
"$eq": ["$$v__id", "$class_id"]
}
}
},
{
"$lookup": {
"from": "assignments",
"let": {
"v__id": "$_id"
},
"localField": "_id",
"foreignField": "student_id",
"pipeline": [
{
"$match": {
"$expr": {
"$eq": ["$$v__id", "$student_id"]
}
}
},
{
"$replaceWith": {
"assignment_title": { "$ifNull": ["$title", null] },
Expand Down Expand Up @@ -734,15 +750,9 @@ mod tests {
{
"$lookup": {
"from": "students",
"let": {
"v__id": "$_id"
},
"localField": "_id",
"foreignField": "classId",
"pipeline": [
{
"$match": { "$expr": {
"$eq": ["$$v__id", "$classId"]
} }
},
{
"$facet": {
"aggregate_count": [
Expand Down Expand Up @@ -862,15 +872,9 @@ mod tests {
{
"$lookup": {
"from": "movies",
"let": {
"v_movie_id": "$movie_id"
},
"localField": "movie_id",
"foreignField": "_id",
"pipeline": [
{
"$match": { "$expr": {
"$eq": ["$$v_movie_id", "$_id"]
} }
},
{
"$replaceWith": {
"year": { "$ifNull": ["$year", null] },
Expand Down Expand Up @@ -997,15 +1001,9 @@ mod tests {
{
"$lookup": {
"from": "movies",
"let": {
"v_movie_id": "$movie_id",
},
"localField": "movie_id",
"foreignField": "_id",
"pipeline": [
{
"$match": { "$expr": {
"$eq": ["$$v_movie_id", "$_id"]
} }
},
{
"$replaceWith": {
"credits": {
Expand Down

0 comments on commit af3cd8b

Please sign in to comment.