Repository: Materials-Consortia/optimade-python-tools

Issue:
Queries with the form: 'value != prop' return entries where 'prop == None' 
For the trajectory endpoint, I added a few references without DOI values.
A query like [https://optimade-trajectories.herokuapp.com/v1/references?filter=%2210.1038/00000%22!=doi](https://optimade-trajectories.herokuapp.com/v1/references?filter=%2210.1038/00000%22!=doi) returned 4 entries, while the query 
[https://optimade-trajectories.herokuapp.com/v1/references?filter=doi!=%2210.1038/00000%22](https://optimade-trajectories.herokuapp.com/v1/references?filter=doi!=%2210.1038/00000%22) returns 2 entries

This also applies to other reference properties like journal and year.

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/Materials-Consortia/optimade-python-tools/pull/1134?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia) Report
> Merging [#1134](https://codecov.io/gh/Materials-Consortia/optimade-python-tools/pull/1134?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia) (c7573b5) into [master](https://codecov.io/gh/Materials-Consortia/optimade-python-tools/commit/0fb4423fcd6ac6d31dabc41c1e767784c2de6829?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia) (0fb4423) will **not change** coverage.
> The diff coverage is `100.00%`.

```diff
@@           Coverage Diff           @@
##           master    #1134   +/-   ##
=======================================
  Coverage   92.33%   92.33%           
=======================================
  Files          68       68           
  Lines        3849     3849           
=======================================
  Hits         3554     3554           
  Misses        295      295           
```

| Flag | Coverage Δ | |
|---|---|---|
| project | `92.33% <100.00%> (ø)` | |
| validator | `92.33% <100.00%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/Materials-Consortia/optimade-python-tools/pull/1134?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia) | Coverage Δ | |
|---|---|---|
| [optimade/filtertransformers/mongo.py](https://codecov.io/gh/Materials-Consortia/optimade-python-tools/pull/1134/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia#diff-b3B0aW1hZGUvZmlsdGVydHJhbnNmb3JtZXJzL21vbmdvLnB5) | `96.66% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Materials-Consortia/optimade-python-tools/pull/1134?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Materials-Consortia/optimade-python-tools/pull/1134?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia). Last update [0fb4423...c7573b5](https://codecov.io/gh/Materials-Consortia/optimade-python-tools/pull/1134?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Materials-Consortia).

ml-evs: Could you add a test that fails without these proposed changes, and passes with them? I imagine you have implicitly done this by adding the extra reference test case, but it would be good to see it clearly.
JPBergsma: I have added a few test for the MongoDB filter transformer.

Patch:
diff --git a/optimade/filtertransformers/mongo.py b/optimade/filtertransformers/mongo.py
index d808ae8f..beba0fcd 100755
--- a/optimade/filtertransformers/mongo.py
+++ b/optimade/filtertransformers/mongo.py
@@ -141,9 +141,9 @@ class MongoTransformer(BaseTransformer):
 
     def constant_first_comparison(self, arg):
         # constant_first_comparison: constant OPERATOR ( non_string_value | not_implemented_string )
-        return {
-            arg[2]: {self.operator_map[self._reversed_operator_map[arg[1]]]: arg[0]}
-        }
+        return self.property_first_comparison(
+            arg[2], {self.operator_map[self._reversed_operator_map[arg[1]]]: arg[0]}
+        )
 
     @v_args(inline=True)
     def value_op_rhs(self, operator, value):


Test patch:
diff --git a/optimade/server/data/test_references.json b/optimade/server/data/test_references.json
index 9dd372ad..05cb7932 100644
--- a/optimade/server/data/test_references.json
+++ b/optimade/server/data/test_references.json
@@ -58,5 +58,25 @@
     "title": "Dummy reference that should remain orphaned from all structures for testing purposes",
     "journal": "JACS",
     "doi": "10.1038/00000"
+  },
+  {
+    "_id": {
+      "$oid": "98fb441f053b1744107019e3"
+    },
+    "id": "dummy/2022",
+    "last_modified": {
+      "$date": "2022-01-23T14:24:37.332Z"
+    },
+    "authors": [
+      {
+        "name": "A Nother",
+        "firstname": "A",
+        "lastname": "Nother"
+      }
+    ],
+    "year": "2019",
+    "note": "Dummy reference",
+    "title": "Just another title",
+    "journal": "JACS"
   }
 ]
diff --git a/tests/filtertransformers/test_mongo.py b/tests/filtertransformers/test_mongo.py
index cf40440e..fec8c2c8 100644
--- a/tests/filtertransformers/test_mongo.py
+++ b/tests/filtertransformers/test_mongo.py
@@ -888,3 +888,8 @@ class TestMongoTransformer:
                 {"number": {"$eq": 0.0}},
             ]
         }
+
+    def test_constant_first_comparisson(self):
+        assert self.transform("nelements != 5") == self.transform("5 != nelements")
+        assert self.transform("nelements > 5") == self.transform("5 < nelements")
+        assert self.transform("nelements <= 5") == self.transform("5 >= nelements")