defradb icon indicating copy to clipboard operation
defradb copied to clipboard

Enable filtering one-many related objects by number of related objects

Open islamaliev opened this issue 7 months ago • 1 comments

At the moment it is possible to filter secondary objects by certain criteria in primary objects. Like so:

query {
	Author(filter: {published: {rating: {_gt: 4.8}}, age: {_gt: 63}}) {
		name
	}
}

But it is not possible to find secondary objects that have no related objects:

query {
	Author(filter: {published: {_eq: null}) {
		name
	}
}

Would be also great to be able to request objects by number of related objects

query {
	Author(filter: {published: {_len: 2}) {
		name
	}
}

But for this a new _len operator needs to be implemented.

Here is a full integration test:

var bookAuthorGQLSchema = (`
	type Book {
		name: String
		rating: Float
		author: Author
	}

	type Author {
		name: String
		age: Int
		verified: Boolean
		published: [Book]
	}
`)

func TestQueryOneToMany_IfFilteredByEmptyRelations_ShouldFind(t *testing.T) {
	test := testUtils.TestCase{
		Actions: []any{
			testUtils.SchemaUpdate{
				Schema: bookAuthorGQLSchema,
			},
			testUtils.CreateDoc{
				CollectionID: 0,
				Doc: `{
					"name": "Painted House",
					"rating": 4.9,
					"author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"
				}`,
			},
			testUtils.CreateDoc{
				CollectionID: 0,
				Doc: `{
					"name": "A Time for Mercy",
					"rating": 4.5,
					"author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"
					}`,
			},
			testUtils.CreateDoc{
				CollectionID: 0,
				Doc: `{
					"name": "Theif Lord",
					"rating": 4.8,
					"author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace"
				}`,
			},
			testUtils.CreateDoc{
				CollectionID: 1,
				// bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b
				Doc: `{
					"name": "John Grisham",
					"age": 65,
					"verified": true
				}`,
			},
			testUtils.CreateDoc{
				CollectionID: 1,
				// bae-72e8c691-9f20-55e7-9228-8af1cf54cace
				Doc: `{
					"name": "Cornelia Funke",
					"age": 62,
					"verified": false
				}`,
			},
			testUtils.CreateDoc{
				CollectionID: 1,
				// bae-6bf29c1c-7112-5f4f-bfae-1c039479acf6
				Doc: `{
					"name": "John Tolkien",
					"age": 70,
					"verified": true
				}`,
			},
			testUtils.Request{
				Request: `query {
					Author(filter: {published: {_eq: null}) {
						name
					}
				}`,
				Results: []map[string]any{{
					"name": "John Tolkien",
				}},
			},
			// would be nice to have this as well
			//testUtils.Request{
			//	Request: `query {
			//		Author(filter: {published: {_len: 2}) {
			//			name
			//		}
			//	}`,
			//	Results: []map[string]any{{
			//		"name": "John Grisham",
			//	}},
			//},
		},
	}
	testUtils.ExecuteTestCase(t, test)
}

islamaliev avatar Jul 09 '24 15:07 islamaliev