Skip to content

Releases: block/elasticgraph

v0.19.0.0

10 Dec 22:53
Compare
Choose a tag to compare

ElasticGraph v0.19.0.0 has been released! This release includes a change to how we treat empty filter predicates, a number of other bug fixes, and many other small changes.

Changes to Treatment of Empty Filter Predicate

ElasticGraph's filtering API supports what we call empty predicates. An empty predicate is one which contains no information. This can take many forms:

field: null
field: {}
field: {gt: null}
field: {subfield: {}}
field: {subfield: {equalToAnyOf: null}}

Most of the time, empty predicates show up when using a query with variables. Here's an example:

query FindArtists(
  $names: [String!] = null
  $yearFormed_gt: Int = null
  $albumNames: [String!] = null
) {
  artists(filter: {
    name: {equalToAnyOf: $names}
    bio: {yearFormed: {gt: $yearFormed_gt}}
    albums: {anySatisfy: {name: {equalToAnyOf: $albumNames}}}
  }) {
    nodes {
      name
      bio {
        yearFormed
      }
      albums {
        name
      }
    }
  }
}

This query supports optional filtering using the nullable variables $names, $yearFormed_gt, and $albumNames. Any of these variables that are submitted as null or omitted when submitting the query will result in an empty predicate.

In prior ElasticGraph versions, empty predicates were ignored. Internally, they were pruned out. For example, if a client submitted the above query with {"yearFormed_gt": 2000}, then ElasticGraph would evaluate the query as if it was this:

query FindArtists(
  $yearFormed_gt: Int = null
) {
  artists(filter: {
    bio: {yearFormed: {gt: $yearFormed_gt}}
  }) {
    nodes {
      name
      bio {
        yearFormed
      }
      albums {
        name
      }
    }
  }
}

While this generally worked great, we realized that this treatment breaks some standard boolean algebra laws when an empty predicate shows up inside an anyOf or a not (as detailed in sections below). In ElasticGraph v0.19.0.0, we now treat empty predicates as matching all documents rather than ignoring them outright. In SQL terms, an empty predicate has the value of TRUE (e.g. WHERE field = "abc" AND TRUE). Under an anyOf an empty predicate now acts like an OR TRUE and under a not it acts like a NOT TRUE.

Impact on anyOf

Previously, empty predicates inside an anyOf: [...] were ignored, leaving only the non-empty predicates. The anyOf would match documents (or not) based on the remaining non-empty predicates. If all predicates were empty, the anyOf would be reduced to [], matching no documents as a result.

This behavior was incorrect; filter: A and filter: {anyOf: [A]} must always return the same results, no matter what A is. With the old behavior, filter: emptyPredicate would match all documents while filter: {anyOf: [emptyPredicate]} would match no documents.

The new treatment of empty predicates fixes this: if an anyOf contains an empty predicate, the anyOf will now match all documents (since the empty predicate itself matches all documents).

Note: anyOf: null is not impacted by this--that expression matched all documents before and continues to match all documents in ElasticGraph v0.19.0.0.

Impact on not

Previously, a not: emptyPredicate expression was ignored. However, according to the laws of boolean algebra, filter: A and filter: {not: A} must be complements. Since filter: emptyPredicate matches all documents, filter: {not: emptyPredicate} must match no documents. The new treatment fixes this.

Upgrade Process

During the upgrade process, we recommend that you carefully audit your client queries to see which ones may be impacted by this change in behavior. In general, a query can only be impacted when it allows an empty predicate (either via a literal null or {}, or via a query variable that could have those values) under anyOf or not. Queries which do not use the anyOf or not operators will not be impacted, and queries which do not allow an empty predicate in those locations will not be impacted. Any queries which may be impacted by this change should be verified to be compatible with the new semantics, or rewritten to be compatible with it.

Breaking Changes

  • Remove anyOf and not from Matches(Phrase|Query)FilterInput. by @myronmarston (in pre-public codebase)
  • Improved the indexer_autoscaler_lambda to manage lambda concurrency instead of SQS event source mapping concurrency to allow it to go past 1000. by @akumar1214 in #13, #14
  • Fix filter boolean algebra bugs related to empty predicates under anyOf and not. by @acerbusace in #8, #22, #6, #39, #40, #41

Bug Fixes

  • Fix filter boolean algebra bugs related to empty predicates under anyOf and not. by @acerbusace in #8, #22, #6, #39, #40, #41
  • Validate variables to make sure they are a JSON object as expected. by @myronmarston in #42
  • Handle too_many_buckets_exception more gracefully. by @myronmarston in #44
  • Fix ArgumentError when grouping sub-aggregations on a nullable field. by @myronmarston (in pre-public codebase)

Dependency Upgrades

Other Improvements

New Contributors

Full Changelog: https://github.com/block/elasticgraph/commits/v0.19.0.0

v0.19.0.0.rc2

05 Dec 16:33
Compare
Choose a tag to compare
v0.19.0.0.rc2 Pre-release
Pre-release

What's Changed

New Contributors

Full Changelog: https://github.com/block/elasticgraph/commits/v0.19.0.0.rc2