Repository: great-expectations/great_expectations

Issue:
TypeError when getting latest validation result from DataContext
**Describe the bug**
I am trying to get the latest validation result from a `DataContext` using the `get_validation_result` method but am getting a

```
Traceback (most recent call last):
  File "C:\workspace\ge_tutorials\get_validation_result_error.py", line 10, in <module>
    latest_validation_result = data_context.get_validation_result("demo")
  File "C:\workspace\ge_tutorials\venv\lib\site-packages\great_expectations\data_context\data_context.py", line 2354, in get_validation_result
    filtered_key_list = sorted(filtered_key_list, key=lambda x: x.run_id)
TypeError: '<' not supported between instances of 'RunIdentifier' and 'RunIdentifier'
```

**To Reproduce**
Steps to reproduce the behavior:
1. [Clone `ge_tutorials`](https://docs.greatexpectations.io/docs/tutorials/getting_started/initialize_a_data_context#set-up-your-machine-for-the-tutorial) as per documentation tutorial
2. Run the following code at project root:
```python
import great_expectations as ge

expectations_root = "./getting_started_tutorial_final_v3_api/great_expectations"

data_context = ge.DataContext(context_root_dir=expectations_root)

# need multiple runs to compare
for _ in range(2):
    data_context.run_checkpoint(
        checkpoint_name="my_checkpoint"
    )
latest_validation_result = data_context.get_validation_result("demo")
print(latest_validation_result)
```

**Expected behavior**
When only the `expectation_suite_name` argument is provided the the `get_validation_result` should proceed to compare all of the validation results and return the latest, e.g. by comparing the timestamp-named subfolders alphabetically.

**Environment (please complete the following information):**
 - Operating System: Windows 10
 - Great Expectations Version: 0.13.26

**Additional context**
The problem boils down to a missing comparison dunder method implementation for the `RunIdentifier` class (or its super class). Currently only the `__eq__` / `__neq__` methods are implemented, at least one more, e.g. `__gt__` or `__lt__`, is need for the `sorted` operation [here](https://github.com/great-expectations/great_expectations/blob/d51afdd1af1ec1627cb5ee541847759255ce3bf1/great_expectations/data_context/data_context.py#L2274).



Discussion:
Thanks for submitting this issue, @zachzIAM ! It sounds like you've done a good chunk of work in determining where the issue lies. Would you be interested in submitting a contribution for this? I'm happy to offer guidance or support wherever possible. 

Resolving patch:
diff --git a/great_expectations/core/data_context_key.py b/great_expectations/core/data_context_key.py
--- a/great_expectations/core/data_context_key.py
+++ b/great_expectations/core/data_context_key.py
@@ -32,6 +32,26 @@ def __eq__(self, other):
     def __ne__(self, other):
         return not self == other
 
+    def __lt__(self, other):
+        if not isinstance(other, self.__class__):
+            return NotImplemented
+        return self.to_tuple() < other.to_tuple()
+
+    def __le__(self, other):
+        if not isinstance(other, self.__class__):
+            return NotImplemented
+        return self.to_tuple() <= other.to_tuple()
+
+    def __gt__(self, other):
+        if not isinstance(other, self.__class__):
+            return NotImplemented
+        return self.to_tuple() > other.to_tuple()
+
+    def __ge__(self, other):
+        if not isinstance(other, self.__class__):
+            return NotImplemented
+        return self.to_tuple() >= other.to_tuple()
+
     def __hash__(self):
         return hash(self.to_tuple())
 


Test patch:
diff --git a/tests/data_context/test_data_context.py b/tests/data_context/test_data_context.py
--- a/tests/data_context/test_data_context.py
+++ b/tests/data_context/test_data_context.py
@@ -390,6 +390,25 @@ def test_data_context_get_validation_result(titanic_data_context):
     assert len(failed_validation_result.results) == 8
 
 
+def test_data_context_get_latest_validation_result(titanic_data_context):
+    """
+    Test that the latest validation result can be correctly fetched from the configured results
+    store
+    """
+    for _ in range(2):
+        titanic_data_context.profile_datasource("mydatasource")
+    assert len(titanic_data_context.validations_store.list_keys()) == 2
+
+    validation_results = [
+        titanic_data_context.validations_store.get(val_key)
+        for val_key in titanic_data_context.validations_store.list_keys()
+    ]
+    latest_validation_result = titanic_data_context.get_validation_result(
+        "mydatasource.mygenerator.Titanic.BasicDatasetProfiler"
+    )
+    assert latest_validation_result in validation_results
+
+
 def test_data_context_get_datasource(titanic_data_context):
     isinstance(titanic_data_context.get_datasource("mydatasource"), LegacyDatasource)