Repository: newrelic/newrelic-node-apollo-server-plugin
Pull request #113 (2021-07-13 22:26:09)

Deepest unique naming
<!--
Thank you for submitting a Pull Request.

This code is leveraged to monitor critical services. Please consider the following:
* Tests are required.
* Performance matters.
* Features that are specific to just your app are unlikely to make it in.

Please fill out the relevant sections as follows:
* Proposed Release Notes: Bulleted list of recommended release notes for the change(s).
* Links: Any relevant links for the change.
* Details: In-depth description of changes, other technical notes, etc.
-->

## Proposed Release Notes

* **BREAKING**: modifies transaction and operation segment/span naming to use deepest *unique* path instead of first deepest path.

  The deepest unique path is the deepest path in the selection set of a query where only one field was selected at each level. 'id' and '__typename' fields are automatically excluded from this decision. For example: `query { libraries { branch booksInStock magazinesInStock }}` will use the path name 'libraries' and  `query { libraries { branch __typename id }}` will use the path name 'libraries.branch'. For more information, see the latest [transaction naming documentation](https://github.com/newrelic/newrelic-node-apollo-server-plugin/blob/main/docs/transactions.md).
  
  This may result in naming changes for your existing GraphQL queries. Any charts, etc. where you are querying by transaction name will need to be updated upon upgrading.

* **BREAKING**: removed the deepest path attribute 'graphql.operation.deepestPath' from operation segments/spans.

## Links

* Closes: https://github.com/newrelic/newrelic-node-apollo-server-plugin/issues/111

## Details

* ~Transaction documentation still needs to be updated.~ 

* Apologies for all the test noise. Needs some further thought but we should consider how we may simplify the tests. Extracting queries + expected parts makes the tests a bit too hard to grok but perhaps we could organize more around queries (instead of output data like transactions/segments) and then have sub tests that assert the expected pieces. Which maybe could mostly share implementation. A thought anyways. While we shouldn't rework transaction naming often, we def have a lot of similar details spread around even with existing shared test files. Made more complicated by the path/operation name used both for segments and transaction name.



Patch:
diff --git a/README.md b/README.md
index ff53aa8..f1cfe33 100644
--- a/README.md
+++ b/README.md
@@ -171,7 +171,7 @@ query {
 }
 ```
 
-`post /query/<anonymous>/libraries.books.author.name`
+`post /query/<anonymous>/libraries.books`
 
 For more information on how transactions are named, including how query errors may impact naming, please see the [transaction documentation](./docs/transactions.md).
 
@@ -183,9 +183,9 @@ Two new metrics have been introduced to understand the behavior of your GraphQL
 
 #### Operation Metrics
 
-`/GraphQL/operation/ApolloServer/[operation-type]/[operation-name]/[deepest-path]`
+`/GraphQL/operation/ApolloServer/[operation-type]/[operation-name]/[deepest-unique-path]`
 
-Operation metrics are very similar to how transaction names are constructed including the operation type, operation name and deepest-path. These metrics represent the durations of the individual queries or mutations and can be used to compare outside of the context of individual transactions which may have multiple queries.
+Operation metrics are very similar to how transaction names are constructed including the operation type, operation name and deepest unique path. These metrics represent the durations of the individual queries or mutations and can be used to compare outside of the context of individual transactions which may have multiple queries.
 
 If you would like to have a list of the top 10 slowest operations, the following query can be used to pull the data on demand or as a part of a dashboard. The 'Bar' chart type is a recommended visualization for this query.
 
@@ -216,11 +216,11 @@ Segments and spans (when Distributed Tracing enabled) are captured for GraphQL o
 
 #### Operation Segments/Spans
 
-`/GraphQL/operation/ApolloServer/[operation-type]/[operation-name]/[deepest-path]`
+`/GraphQL/operation/ApolloServer/[operation-type]/[operation-name]/[deepest-unique-path]`
 
-Operation segments/spans include the operation type, operation name and deepest-path. These represent the individual duration and attributes of a specific invocation within a transaction or trace.
+Operation segments/spans include the operation type, operation name and deepest unique path. These represent the individual duration and attributes of a specific invocation within a transaction or trace.
 
-The operation type, operation name and deepest-path are captured as attributes on a segment or span as well as the query with obfuscated arguments.
+The operation type and operation name are captured as attributes on a segment or span as well as the query with obfuscated arguments.
 
 For more information on collected attributes, see the [segments and spans documentation](./docs/segments-and-spans.md)
 
diff --git a/docs/metrics.md b/docs/metrics.md
index d0c30a2..81a4e33 100644
--- a/docs/metrics.md
+++ b/docs/metrics.md
@@ -6,7 +6,7 @@ For more information on querying metrics and creating charts, see the [Resources
 
 ## Operation Metrics
 
-`/GraphQL/operation/ApolloServer/[operation-type]/[operation-name]/[deepest-path]`
+`/GraphQL/operation/ApolloServer/[operation-type]/[operation-name]/[deepest-unique-path]`
 
 Operation metrics include the operation type, operation name and deepest-path. These metrics represent the durations of the individual queries or mutations and can be used to compare outside of the context of individual transactions which may have multiple queries.
 
@@ -14,7 +14,7 @@ Operation metrics include the operation type, operation name and deepest-path. T
 
 **Operation Name:** The operation name when provided or `<anonymous>`.
 
-**Deepest Path:** The deepest path resolved (or attempted in the case of a validation error). Since operation names may be reused, this helps further determine uniqueness of a given operation.
+**Deepest Unique Path:** The deepest path included in the selection set of a query where only one field was selected at each level. Since operation names may be reused, this helps further determine uniqueness of a given operation. See the description on the [transactions](./transactions.md#deepest-unique-path) page for more details.
 
 ## Field Resolve Metrics
 
diff --git a/docs/segments-and-spans.md b/docs/segments-and-spans.md
index 24263ad..9ad82ba 100644
--- a/docs/segments-and-spans.md
+++ b/docs/segments-and-spans.md
@@ -4,9 +4,11 @@ Segments and spans (when Distributed Tracing enabled) are captured for GraphQL o
 
 ## Operation Segments/Spans
 
-`/GraphQL/operation/ApolloServer/[operation-type]/[operation-name]/[deepest-path]`
+`/GraphQL/operation/ApolloServer/[operation-type]/[operation-name]/[deepest-unique-path]`
 
-Operation segments/spans include the operation type, operation name and deepest-path. These represent the individual duration and attributes of a specific invocation within a transaction or trace.
+Operation segments/spans include the operation type, operation name and deepest unique path. These represent the individual duration and attributes of a specific invocation within a transaction or trace.
+
+For more details on the parts, see the [transactions](./transactions.md#details) page.
 
 **Attributes**
 
@@ -14,7 +16,6 @@ Operation segments/spans include the operation type, operation name and deepest-
 | ---------------------- | ---------------- | -------- |
 | graphql.operation.type | query or mutation| included |
 | graphql.operation.name | Name given to the operation or anonymous | included |
-| graphql.operation.deepestPath | Deepest path resolved as the part of an operation | included |
 | graphql.operation.query | The original GraphQL query with arguments obfuscated | included |
 
 To exclude capture of the query attribute (or any attribute), the attribute name will need to be added to the 'attributes' exclude list or segment/span attributes exclude lists individually.
diff --git a/docs/transactions.md b/docs/transactions.md
index 73addcd..2a723e1 100644
--- a/docs/transactions.md
+++ b/docs/transactions.md
@@ -13,7 +13,7 @@ query {
 }
 ```
 
-`post /query/<anonymous>/libraries.books.author.name`
+`post /query/<anonymous>/libraries.books`
 
 ---
 
@@ -21,21 +21,88 @@ Transactions are captured as web transactions, associated with the underlying fr
 
 We leverage several details in a transaction name to attempt to mostly group unique query representations: http method, operation type, operation name and the deepest path resolved (the first, if multiple).
 
-The raw representation of a transaction looks like the following: `/WebTransaction/{framework-name}/POST//{operation-type}/{operation-name}/{deepest-path}`
+The raw representation of a transaction looks like the following: `/WebTransaction/{framework-name}/POST//{operation-type}/{operation-name}/{deepest-unique-path}`
 
-For an Express usage of Apollo Server, that may look like: `/WebTransaction/Expressjs/POST//query/<anonymous>/libraries.books.author.name`
+For an Express usage of Apollo Server, that may look like: `/WebTransaction/Expressjs/POST//query/<anonymous>/libraries.books`
 
-The transaction on New Relic One will ultimately display similar to: `post /query/<anonymous>/libraries.books.author.name`.
+The transaction on New Relic One will ultimately display similar to: `post /query/<anonymous>/libraries.books`.
 
 ## Details
 
-**Http Method:** Http method/verb for the web request. Data may be requested via GET or POST and is surfaced to differentiate similar to other web transactions.
+### Http Method
 
-**Operation Type:** Indicates if the operation was a query or a mutation.
+Http method/verb for the web request. Data may be requested via GET or POST and is surfaced to differentiate similar to other web transactions.
 
-**Operation Name:** The operation name when provided or `<anonymous>`.
+### Operation Type
 
-**Deepest Path:** The deepest path resolved (or attempted in the case of a validation error). Since operation names may be reused, this helps further determine uniqueness of a given operation.
+Indicates if the operation was a query or a mutation.
+
+### Operation Name
+
+The operation name when provided or `<anonymous>`.
+
+`query { libraries }` would use the operation name '<anonymous>' because a name was not provided.
+
+A named query such as `query GetLibraries { libraries }` would use the operation name `GetLibraries'.
+
+### Deepest Unique Path
+
+The deepest path included in the selection set of a query where only one field was selected at each level. Since operation names may be reused, this helps further determine uniqueness of a given operation.
+
+We use the deepest unique path (instead of deepest path like prior) to avoid making arbitrary decision in naming, which may imply/hide details of what could cause slowness for an application.
+
+For the query:
+
+```
+query {
+  libraries {
+    branch
+    booksInStock {
+      isbn,
+      title,
+      author
+    }
+    magazinesInStock {
+      issue,
+      title
+    }
+  }
+}
+```
+
+We will select a deepest unique path of 'libraries' as we select multiple fields beyond that point. Any resolver executed beyond that point may contribute to the performance characteristics of the transaction.
+
+If the query were to only select one field per resolver, we select the full path as each selection set is unique.
+
+The query:
+
+```
+query {
+  libraries {
+    booksInStock {
+      title
+    }
+  }
+}
+```
+
+Will result in the deepest unique path: 'libraries.booksInStock.title'.
+
+`id` and `__typename` fields are automatically excluded from the naming decision.
+
+For example, a federated sub graph query:
+
+```
+query {
+  libraries {
+    branch
+    __typename
+    id
+  }
+}
+```
+
+Would result in the deepest unique path of: 'libraries.branch'.
 
 ## Naming on Error
 
@@ -53,7 +120,6 @@ Below is an example of querying for a field that does not exist (`doesnotexist`)
 query GetBooksByLibrary {
   libraries {
     books {
-      title
       doesnotexist {
         name
       }
@@ -91,7 +157,7 @@ In these situations, the `query` attribute on the operation span associated with
 
 Apollo Server allows the sending of batch queries. In these situations, there are multiple operation/queries in play to impact naming.
 
-To continue to best uniquely identify transaction groupings, we aggregate the operation names after an additional `/batch` indicator. These names are likely to be quite long. We are considering dropping the deepest-path from these names but are currently maintaining consistency.
+To continue to best uniquely identify transaction groupings, we aggregate the operation names after an additional `/batch` indicator. These names are likely to be quite long. We are considering dropping the deepest unique path from these names but are currently maintaining consistency.
 
 Below is an example of a batch query and what that may look like in NR One.
 
@@ -117,6 +183,6 @@ Below is an example of a batch query and what that may look like in NR One.
 ]
 ```
 
-`post /batch/query/GetBookForLibrary/library.books.author.name/mutation/<anonymous>/addThing`
+`post /batch/query/GetBookForLibrary/library.books/mutation/<anonymous>/addThing`
 
-Here you see `batch/` followed by `query/GetBookForLibrary/library.books.author.name` and `mutation/<anonymous>/addThing`.
\ No newline at end of file
+Here you see `batch/` followed by `query/GetBookForLibrary/library.books` and `mutation/<anonymous>/addThing`.
diff --git a/lib/create-plugin.js b/lib/create-plugin.js
index 4ec28d1..dd1dae4 100644
--- a/lib/create-plugin.js
+++ b/lib/create-plugin.js
@@ -27,9 +27,11 @@ const FIELD_PATH_ATTR = 'graphql.field.path'
 const FIELD_ARGS_ATTR = 'graphql.field.args'
 const OPERATION_TYPE_ATTR = 'graphql.operation.type'
 const OPERATION_NAME_ATTR = 'graphql.operation.name'
-const OPERATION_PATH_ATTR = 'graphql.operation.deepestPath'
 const OPERATION_QUERY_ATTR = 'graphql.operation.query'
+
 const INTROSPECTION_TYPES = ['__schema', '__type']
+const IGNORED_PATH_FIELDS = ['id', '__typename']
+
 const DESTINATIONS = {
   NONE: 0x00
 }
@@ -214,7 +216,7 @@ function createPlugin(instrumentationApi, config = {}) {
           const operationDetails = getOperationDetails(responseContext)
 
           if (operationDetails) {
-            const {operationName, operationType, deepestPath} = operationDetails
+            const {operationName, operationType, deepestUniquePath} = operationDetails
 
             operationSegment.addAttribute(OPERATION_TYPE_ATTR, operationType)
 
@@ -226,10 +228,8 @@ function createPlugin(instrumentationApi, config = {}) {
             let formattedOperation = `${operationType}/${formattedName}`
 
             // Certain requests, such as introspection, won't hit any resolvers
-            if (deepestPath) {
-              operationSegment.addAttribute(OPERATION_PATH_ATTR, deepestPath)
-
-              formattedOperation += `/${deepestPath}`
+            if (deepestUniquePath) {
+              formattedOperation += `/${deepestUniquePath}`
             }
 
             segmentName = formattedOperation
@@ -289,13 +289,14 @@ function isTopLevelField(fieldInfo) {
 function getDetailsFromDocument(document) {
   const [ definition ] = document.definitions
 
-  const deepestSelectionPath = getDeepestSelectionPath(definition)
+  const deepestUniquePath = getDeepestUniqueSelection(definition)
+
   const definitionName = definition.name && definition.name.value
 
   return {
     operationType: definition.operation,
     operationName: definitionName,
-    deepestPath: deepestSelectionPath.join('.')
+    deepestUniquePath: deepestUniquePath.join('.')
   }
 }
 
@@ -340,39 +341,37 @@ function setTransactionName(transaction, transactionName) {
 }
 
 /**
- * Returns the deepest path as an array of parts
- * from an apollo-server document definition.
+ * Returns the deepest path in the document definition selectionSet
+ * where only one field was selected.
+ *
+ * 'id' and '__typename' fields are filtered out of consideration to improve
+ * naming in sub graph scenarioes.
  */
-function getDeepestSelectionPath(definition) {
-  let deepestPath = null
-
-  definition.selectionSet.selections.forEach((selection) => {
-    searchSelection(selection)
-  })
+function getDeepestUniqueSelection(definition) {
+  const deepestPath = []
+  let selection = definition
+  while (selection.selectionSet) {
+    const filtered = selection.selectionSet.selections.filter((currentSelection) => {
+      // Inline fragments describe the prior element (_entities) but contain
+      // selections for further naming.
+      if (currentSelection.kind === 'InlineFragment') {
+        return true
+      }
 
-  return deepestPath
+      return IGNORED_PATH_FIELDS.indexOf(currentSelection.name.value) < 0
+    })
 
-  /**
-   * Search each selection path until no-more sub-selections
-   * exist. If the curent path is deeper than deepestPath,
-   * deepestPath is replaced.
-   */
-  function searchSelection(selection, currentParts) {
-    const parts = currentParts ? [...currentParts] : []
-
-    // we have found that when queries contain InlineFragments
-    // they lack `name` property, check for property before adding to parts
-    // see https://github.com/newrelic/newrelic-node-apollo-server-plugin/issues/84
-    selection.name && parts.push(selection.name.value)
-
-    if (selection.selectionSet) {
-      selection.selectionSet.selections.forEach((innerSelection) => {
-        searchSelection(innerSelection, parts)
-      })
-    } else if (!deepestPath || parts.length > deepestPath.length) {
-      deepestPath = parts
+    if (filtered.length > 1) {
+      break // selections not unique
     }
+
+    selection = filtered[0]
+
+    // Inline fragments do not have a name.
+    selection.name && deepestPath.push(selection.name.value)
   }
+
+  return deepestPath
 }
 
 function recordResolveSegment(segment, scope) {


Test patch:
diff --git a/tests/integration/config-capture-scalars.test.js b/tests/integration/config-capture-scalars.test.js
index 855cc93..e99b25b 100644
--- a/tests/integration/config-capture-scalars.test.js
+++ b/tests/integration/config-capture-scalars.test.js
@@ -57,10 +57,10 @@ function createNoScalarTests(t) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [
@@ -132,10 +132,10 @@ function createScalarTests(t) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [
@@ -190,4 +190,3 @@ function createScalarTests(t) {
     })
   })
 }
-
diff --git a/tests/integration/metrics.test.js b/tests/integration/metrics.test.js
index c9dd59c..e2794d1 100644
--- a/tests/integration/metrics.test.js
+++ b/tests/integration/metrics.test.js
@@ -83,10 +83,10 @@ function createMetricsTests(t) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', () => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
 
       t.metrics([
         `${OPERATION_PREFIX}/${operationPart}`,
@@ -121,12 +121,12 @@ function createMetricsTests(t) {
       addThing(name: "added thing!")
     }`
 
-    const deepestPath1 = 'library.books.author.name'
+    const path1 = 'library.books'
 
     const queries = [query1, query2]
 
     helper.agent.on('transactionFinished', () => {
-      const operationPart1 = `query/${expectedName1}/${deepestPath1}`
+      const operationPart1 = `query/${expectedName1}/${path1}`
       const operationPart2 = `mutation/${ANON_PLACEHOLDER}/addThing`
 
       const operationMetrics1 = [
@@ -154,7 +154,7 @@ function createMetricsTests(t) {
     const { helper, serverUrl } = t.context
 
     const query = '{ libraries { books { title author { name } } } }'
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
     const querySha = crypto.createHash('sha256').update(query).digest('hex')
     const withQuery = `${serverUrl}?extensions={"persistedQuery":{"version":1,
       "sha256Hash":"${querySha}"}}&query=${query}`
@@ -162,7 +162,7 @@ function createMetricsTests(t) {
       "sha256Hash":"${querySha}"}}`
 
     helper.agent.on('transactionFinished', () => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
 
       t.metrics([
         `${OPERATION_PREFIX}/${operationPart}`,
diff --git a/tests/versioned/apollo-federation/package.json b/tests/versioned/apollo-federation/package.json
index 94f12e6..5e8cab3 100644
--- a/tests/versioned/apollo-federation/package.json
+++ b/tests/versioned/apollo-federation/package.json
@@ -13,7 +13,9 @@
         "apollo-server": ">=2.25.1 <3.0.0"
       },
       "files": [
-        "segments.test.js"
+        "segments.test.js",
+        "transaction-naming.test.js",
+        "sub-graph-transactions.test.js"
       ]
     },
     {
@@ -27,7 +29,9 @@
         "apollo-server": "2.25.1"
       },
       "files": [
-        "segments.test.js"
+        "segments.test.js",
+        "transaction-naming.test.js",
+        "sub-graph-transactions.test.js"
       ]
     }
   ],
diff --git a/tests/versioned/apollo-federation/segments.test.js b/tests/versioned/apollo-federation/segments.test.js
index 3729eca..394df2d 100644
--- a/tests/versioned/apollo-federation/segments.test.js
+++ b/tests/versioned/apollo-federation/segments.test.js
@@ -55,7 +55,7 @@ function createFederatedSegmentsTests(t, frameworkName) {
       const bookExternal = formatExternalSegment(t.context.bookUrl)
       const magazineExternal = formatExternalSegment(t.context.magazineUrl)
 
-      const operationPart = `query/${ANON_PLACEHOLDER}/libraries.booksInStock.isbn`
+      const operationPart = `query/${ANON_PLACEHOLDER}/libraries`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -91,7 +91,6 @@ function createFederatedSegmentsTests(t, frameworkName) {
     const booksQueryName = 'GetBooksForLibraries'
     const booksQuery = `query ${booksQueryName} {
       libraries {
-        branch
         booksInStock {
           isbn,
           title,
@@ -103,7 +102,6 @@ function createFederatedSegmentsTests(t, frameworkName) {
     const magazineQueryName = 'GetMagazinesForLibraries'
     const magazineQuery = `query ${magazineQueryName} {
       libraries {
-        branch
         magazinesInStock {
           issue,
           title
@@ -122,9 +120,9 @@ function createFederatedSegmentsTests(t, frameworkName) {
         return
       }
 
-      const operationPart1 = `query/${booksQueryName}/libraries.booksInStock.isbn`
+      const operationPart1 = `query/${booksQueryName}/libraries.booksInStock`
       const expectedQuery1Name = `${operationPart1}`
-      const operationPart2 = `query/${magazineQueryName}/libraries.magazinesInStock.issue`
+      const operationPart2 = `query/${magazineQueryName}/libraries.magazinesInStock`
       const expectedQuery2Name = `${operationPart2}`
 
       const batchTransactionPrefix = `${TRANSACTION_PREFIX}//batch`
diff --git a/tests/versioned/apollo-federation/transaction-inline-fragments.test.js b/tests/versioned/apollo-federation/sub-graph-transactions.test.js
similarity index 60%
rename from tests/versioned/apollo-federation/transaction-inline-fragments.test.js
rename to tests/versioned/apollo-federation/sub-graph-transactions.test.js
index b8fa33c..849abe2 100644
--- a/tests/versioned/apollo-federation/transaction-inline-fragments.test.js
+++ b/tests/versioned/apollo-federation/sub-graph-transactions.test.js
@@ -11,7 +11,7 @@ const { setupFederatedGatewayServerTests } = require('./federated-gateway-server
 const { checkResult } = require('../common')
 
 setupFederatedGatewayServerTests({
-  suiteName: 'query with inline fragments',
+  suiteName: 'sub graph transaction naming',
   createTests: createFederatedSegmentsTests,
   instrumentSubGraphs: true
 })
@@ -23,7 +23,7 @@ setupFederatedGatewayServerTests({
  * @param {*} t a tap test instance
  */
 function createFederatedSegmentsTests(t) {
-  t.test('should nest sub graphs under operation', (t) => {
+  t.test('should properly name when inline fragments exist', (t) => {
     const { helper, serverUrl } = t.context
 
     /**
@@ -48,10 +48,10 @@ function createFederatedSegmentsTests(t) {
      *   }
      * }`
      * The ones with `...on Library` are [InlineFragments](https://graphql.org/learn/queries/#inline-fragments)
-     * which lack name properites on all the selections within document
-     * without the fix in https://github.com/newrelic/newrelic-node-apollo-server-plugin/pull/100
+     * which lack name properites on all the selections within document.
+     * Without the fix in https://github.com/newrelic/newrelic-node-apollo-server-plugin/pull/100
      * they would crash and not properly name the transactions, also the query request
-     * would fail
+     * would fail.
      */
     const query = `query SubGraphs {
       libraries {
@@ -71,9 +71,9 @@ function createFederatedSegmentsTests(t) {
     let transactions = []
     const expectedTransactions = [
       'WebTransaction/Expressjs/POST//query/<anonymous>/libraries.branch',
-      'WebTransaction/Expressjs/POST//query/<anonymous>/_entities.booksInStock.isbn',
-      'WebTransaction/Expressjs/POST//query/<anonymous>/_entities.magazinesInStock.issue',
-      'WebTransaction/Expressjs/POST//query/SubGraphs/libraries.booksInStock.isbn'
+      'WebTransaction/Expressjs/POST//query/<anonymous>/_entities.booksInStock',
+      'WebTransaction/Expressjs/POST//query/<anonymous>/_entities.magazinesInStock',
+      'WebTransaction/Expressjs/POST//query/SubGraphs/libraries'
     ]
 
     helper.agent.on('transactionFinished', (transaction) => {
@@ -82,7 +82,60 @@ function createFederatedSegmentsTests(t) {
 
     executeQuery(serverUrl, query, (err, result) => {
       t.equal(transactions.length, 4, 'should create 4 transactions')
-      t.same(expectedTransactions, transactions, 'should properly name each transaction')
+
+      t.same(transactions, expectedTransactions, 'should properly name each transaction')
+      t.error(err)
+      checkResult(t, result, () => {
+        t.end()
+      })
+    })
+  })
+
+  t.test('should filter id and __typename fields from unique naming', (t) => {
+    const { helper, serverUrl } = t.context
+
+    /**
+     * The 'libraries' sub graph service gets queried as:
+     * query {
+     *   libraries {
+     *     branch
+     *     __typename
+     *     id
+     *   }
+     * }
+     *
+     * 'id' and '__typename' should get filtered out for a
+     * specific name of 'libraries.branch'.
+     */
+    const query = `query SubGraphs {
+      libraries {
+        branch
+        booksInStock {
+          isbn,
+          title,
+          author
+        }
+        magazinesInStock {
+          issue,
+          title
+        }
+      }
+    }`
+
+    let transactions = []
+    const expectedPath = 'libraries.branch'
+    const expectedTransaction
+      = `WebTransaction/Expressjs/POST//query/<anonymous>/${expectedPath}`
+
+    helper.agent.on('transactionFinished', (transaction) => {
+      transactions.push(transaction.name)
+    })
+
+    executeQuery(serverUrl, query, (err, result) => {
+      const hasTransaction = transactions.indexOf(expectedTransaction) >= 0
+
+      t.ok(hasTransaction, `should have a transaction named: '${expectedTransaction}'`)
+
       t.error(err)
       checkResult(t, result, () => {
         t.end()
diff --git a/tests/versioned/apollo-federation/transaction-naming.test.js b/tests/versioned/apollo-federation/transaction-naming.test.js
index 9ae01d0..95aa6fa 100644
--- a/tests/versioned/apollo-federation/transaction-naming.test.js
+++ b/tests/versioned/apollo-federation/transaction-naming.test.js
@@ -26,7 +26,7 @@ setupFederatedGatewayServerTests({
 function createFederatedTransactionNamingTests(t, frameworkName) {
   const TRANSACTION_PREFIX = `WebTransaction/${frameworkName}/POST`
 
-  t.test('should properly name transaction when an anonymous federated query', (t) => {
+  t.test('anonymous query, multi selections should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const query = `query {
@@ -49,9 +49,8 @@ function createFederatedTransactionNamingTests(t, frameworkName) {
         return
       }
 
-      const operationPart = `query/${ANON_PLACEHOLDER}/libraries.booksInStock.isbn`
-      t.equal(transaction.name,
-      `${TRANSACTION_PREFIX}//${operationPart}`)
+      const operationPart = `query/${ANON_PLACEHOLDER}/libraries`
+      t.equal(transaction.name, `${TRANSACTION_PREFIX}//${operationPart}`)
     })
 
     executeQuery(serverUrl, query, (err, result) => {
@@ -62,7 +61,35 @@ function createFederatedTransactionNamingTests(t, frameworkName) {
     })
   })
 
-  t.test('should properly name transaction when a named, federated query', (t) => {
+  t.test('anonymous query, single selections should return deepest unique path', (t) => {
+    const { helper, serverUrl } = t.context
+
+    const query = `query {
+      libraries {
+        booksInStock {
+          title
+        }
+      }
+    }`
+
+    helper.agent.on('transactionFinished', (transaction) => {
+      if (shouldSkipTransaction(transaction)) {
+        return
+      }
+
+      const operationPart = `query/${ANON_PLACEHOLDER}/libraries.booksInStock.title`
+      t.equal(transaction.name, `${TRANSACTION_PREFIX}//${operationPart}`)
+    })
+
+    executeQuery(serverUrl, query, (err, result) => {
+      t.error(err)
+      checkResult(t, result, () => {
+        t.end()
+      })
+    })
+  })
+
+  t.test('named query, multi selections should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const query = `query booksInStock {
@@ -75,14 +102,41 @@ function createFederatedTransactionNamingTests(t, frameworkName) {
       }
     }`
 
+    helper.agent.on('transactionFinished', (transaction) => {
+      if (shouldSkipTransaction(transaction)) {
+        return
+      }
+
+      const operationPart = 'query/booksInStock/libraries'
+      t.equal(transaction.name, `${TRANSACTION_PREFIX}//${operationPart}`)
+    })
+
+    executeQuery(serverUrl, query, (err, result) => {
+      t.error(err)
+      checkResult(t, result, () => {
+        t.end()
+      })
+    })
+  })
+
+  t.test('named query, single selections should return deepest unique path', (t) => {
+    const { helper, serverUrl } = t.context
+
+    const query = `query booksInStock {
+      libraries {
+        booksInStock {
+          title
+        }
+      }
+    }`
+
     helper.agent.on('transactionFinished', (transaction) => {
       if (shouldSkipTransaction(transaction)) {
         return
       }
 
       const operationPart = 'query/booksInStock/libraries.booksInStock.title'
-      t.equal(transaction.name,
-      `${TRANSACTION_PREFIX}//${operationPart}`)
+      t.equal(transaction.name, `${TRANSACTION_PREFIX}//${operationPart}`)
     })
 
     executeQuery(serverUrl, query, (err, result) => {
@@ -99,7 +153,6 @@ function createFederatedTransactionNamingTests(t, frameworkName) {
     const booksQueryName = 'GetBooksForLibraries'
     const booksQuery = `query ${booksQueryName} {
       libraries {
-        branch
         booksInStock {
           isbn,
           title,
@@ -111,7 +164,6 @@ function createFederatedTransactionNamingTests(t, frameworkName) {
     const magazineQueryName = 'GetMagazinesForLibraries'
     const magazineQuery = `query ${magazineQueryName} {
       libraries {
-        branch
         magazinesInStock {
           issue,
           title
@@ -125,12 +177,13 @@ function createFederatedTransactionNamingTests(t, frameworkName) {
       if (shouldSkipTransaction(transaction)) {
         return
       }
-      const operationPart1 = `query/${booksQueryName}/libraries.booksInStock.isbn`
-      const operationPart2 = `query/${magazineQueryName}/libraries.magazinesInStock.issue`
+      const operationPart1 = `query/${booksQueryName}/libraries.booksInStock`
+      const operationPart2 = `query/${magazineQueryName}/libraries.magazinesInStock`
 
       const batchTransactionPrefix = `${TRANSACTION_PREFIX}//batch`
 
-      t.equal(transaction.name,
+      t.equal(
+        transaction.name,
         `${batchTransactionPrefix}/${operationPart1}/${operationPart2}`
       )
     })
@@ -145,4 +198,3 @@ function createFederatedTransactionNamingTests(t, frameworkName) {
     })
   })
 }
-
diff --git a/tests/versioned/apollo-server-fastify/segments.test.js b/tests/versioned/apollo-server-fastify/segments.test.js
index 8356907..4c1b3fc 100644
--- a/tests/versioned/apollo-server-fastify/segments.test.js
+++ b/tests/versioned/apollo-server-fastify/segments.test.js
@@ -93,7 +93,6 @@ function createFastifySegmentsTests(t, frameworkName) {
     const query = `query {
       libraries {
         books {
-          title
           author {
             name
           }
@@ -101,10 +100,10 @@ function createFastifySegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books.author.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -129,7 +128,7 @@ function createFastifySegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level should return deepest path', (t) => {
+  t.test('named query, multi-level should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -144,10 +143,10 @@ function createFastifySegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -173,48 +172,6 @@ function createFastifySegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level, should choose *first* deepest-path', (t) => {
-    const { helper, serverUrl } = t.context
-
-    const expectedName = 'GetBooksByLibrary'
-    const query = `query ${expectedName} {
-      libraries {
-        books {
-          title
-          isbn
-        }
-      }
-    }`
-
-    // .isbn is the same length but title will be first so that path should be used
-    const firstDeepestPath = 'libraries.books.title'
-
-    helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${firstDeepestPath}`
-      const expectedSegments = [{
-        name: `${TRANSACTION_PREFIX}//${operationPart}`,
-        children: [{
-          name: `${OPERATION_PREFIX}/${operationPart}`,
-          children: [
-            { name: `${RESOLVE_PREFIX}/libraries` },
-            { name: `${RESOLVE_PREFIX}/libraries.books` },
-            { name: `${RESOLVE_PREFIX}/libraries.books.title` },
-            { name: `${RESOLVE_PREFIX}/libraries.books.isbn` }
-          ]
-        }]
-      }]
-
-      t.segments(transaction.trace.root, expectedSegments)
-    })
-
-    executeQuery(serverUrl, query, (err, result) => {
-      t.error(err)
-      checkResult(t, result, () => {
-        t.end()
-      })
-    })
-  })
-
   t.test('anonymous mutation, single level', (t) => {
     const { helper, serverUrl } = t.context
 
@@ -364,10 +321,10 @@ function createFastifySegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -420,12 +377,12 @@ function createFastifySegmentsTests(t, frameworkName) {
       addThing(name: "added thing!")
     }`
 
-    const deepestPath1 = 'library.books.author.name'
+    const path = 'library.books'
 
     const queries = [query1, query2]
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart1 = `query/${expectedName1}/${deepestPath1}`
+      const operationPart1 = `query/${expectedName1}/${path}`
       const expectedQuery1Name = `${operationPart1}`
       const operationPart2 = `mutation/${ANON_PLACEHOLDER}/addThing`
       const expectedQuery2Name = `${operationPart2}`
@@ -529,7 +486,6 @@ function createFastifySegmentsTests(t, frameworkName) {
     const invalidQuery = `query {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
@@ -537,10 +493,10 @@ function createFastifySegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books.doesnotexist.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -565,4 +521,3 @@ function createFastifySegmentsTests(t, frameworkName) {
     })
   })
 }
-
diff --git a/tests/versioned/apollo-server-hapi/segments.test.js b/tests/versioned/apollo-server-hapi/segments.test.js
index cd75c69..33ac248 100644
--- a/tests/versioned/apollo-server-hapi/segments.test.js
+++ b/tests/versioned/apollo-server-hapi/segments.test.js
@@ -99,7 +99,6 @@ function createHapiSegmentsTests(t, frameworkName) {
     const query = `query {
       libraries {
         books {
-          title
           author {
             name
           }
@@ -107,10 +106,10 @@ function createHapiSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books.author.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -138,7 +137,7 @@ function createHapiSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level should return deepest path', (t) => {
+  t.test('named query, multi-level should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -153,10 +152,10 @@ function createHapiSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -185,51 +184,6 @@ function createHapiSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level, should choose *first* deepest-path', (t) => {
-    const { helper, serverUrl } = t.context
-
-    const expectedName = 'GetBooksByLibrary'
-    const query = `query ${expectedName} {
-      libraries {
-        books {
-          title
-          isbn
-        }
-      }
-    }`
-
-    // .isbn is the same length but title will be first so that path should be used
-    const firstDeepestPath = 'libraries.books.title'
-
-    helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${firstDeepestPath}`
-      const expectedSegments = [{
-        name: `${TRANSACTION_PREFIX}//${operationPart}`,
-        children: [{
-          name: 'Nodejs/Middleware/Hapi/handler//gql',
-            children: [{
-              name: `${OPERATION_PREFIX}/${operationPart}`,
-              children: [
-                { name: `${RESOLVE_PREFIX}/libraries` },
-                { name: `${RESOLVE_PREFIX}/libraries.books` },
-                { name: `${RESOLVE_PREFIX}/libraries.books.title` },
-                { name: `${RESOLVE_PREFIX}/libraries.books.isbn` }
-              ]
-            }]
-        }]
-      }]
-
-      t.segments(transaction.trace.root, expectedSegments)
-    })
-
-    executeQuery(serverUrl, query, (err, result) => {
-      t.error(err)
-      checkResult(t, result, () => {
-        t.end()
-      })
-    })
-  })
-
   t.test('anonymous mutation, single level', (t) => {
     const { helper, serverUrl } = t.context
 
@@ -391,10 +345,10 @@ function createHapiSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -450,12 +404,12 @@ function createHapiSegmentsTests(t, frameworkName) {
       addThing(name: "added thing!")
     }`
 
-    const deepestPath1 = 'library.books.author.name'
+    const path1 = 'library.books'
 
     const queries = [query1, query2]
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart1 = `query/${expectedName1}/${deepestPath1}`
+      const operationPart1 = `query/${expectedName1}/${path1}`
       const expectedQuery1Name = `${operationPart1}`
       const operationPart2 = `mutation/${ANON_PLACEHOLDER}/addThing`
       const expectedQuery2Name = `${operationPart2}`
@@ -565,7 +519,6 @@ function createHapiSegmentsTests(t, frameworkName) {
     const invalidQuery = `query {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
@@ -573,10 +526,10 @@ function createHapiSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books.doesnotexist.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -604,4 +557,3 @@ function createHapiSegmentsTests(t, frameworkName) {
     })
   })
 }
-
diff --git a/tests/versioned/apollo-server-koa/segments.test.js b/tests/versioned/apollo-server-koa/segments.test.js
index 33ce99f..8ddf56b 100644
--- a/tests/versioned/apollo-server-koa/segments.test.js
+++ b/tests/versioned/apollo-server-koa/segments.test.js
@@ -99,7 +99,6 @@ function createKoaSegmentsTests(t, frameworkName) {
     const query = `query {
       libraries {
         books {
-          title
           author {
             name
           }
@@ -107,10 +106,10 @@ function createKoaSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books.author.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -138,7 +137,7 @@ function createKoaSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level should return deepest path', (t) => {
+  t.test('named query, multi-level should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -153,10 +152,10 @@ function createKoaSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -185,51 +184,6 @@ function createKoaSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level, should choose *first* deepest-path', (t) => {
-    const { helper, serverUrl } = t.context
-
-    const expectedName = 'GetBooksByLibrary'
-    const query = `query ${expectedName} {
-      libraries {
-        books {
-          title
-          isbn
-        }
-      }
-    }`
-
-    // .isbn is the same length but title will be first so that path should be used
-    const firstDeepestPath = 'libraries.books.title'
-
-    helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${firstDeepestPath}`
-      const expectedSegments = [{
-        name: `${TRANSACTION_PREFIX}//${operationPart}`,
-        children: [{
-          name: 'Nodejs/Middleware/Koa',
-            children: [{
-              name: `${OPERATION_PREFIX}/${operationPart}`,
-              children: [
-                { name: `${RESOLVE_PREFIX}/libraries` },
-                { name: `${RESOLVE_PREFIX}/libraries.books` },
-                { name: `${RESOLVE_PREFIX}/libraries.books.title` },
-                { name: `${RESOLVE_PREFIX}/libraries.books.isbn` }
-              ]
-            }]
-        }]
-      }]
-
-      t.segments(transaction.trace.root, expectedSegments)
-    })
-
-    executeQuery(serverUrl, query, (err, result) => {
-      t.error(err)
-      checkResult(t, result, () => {
-        t.end()
-      })
-    })
-  })
-
   t.test('anonymous mutation, single level', (t) => {
     const { helper, serverUrl } = t.context
 
@@ -391,10 +345,10 @@ function createKoaSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -450,12 +404,12 @@ function createKoaSegmentsTests(t, frameworkName) {
       addThing(name: "added thing!")
     }`
 
-    const deepestPath1 = 'library.books.author.name'
+    const path1 = 'library.books'
 
     const queries = [query1, query2]
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart1 = `query/${expectedName1}/${deepestPath1}`
+      const operationPart1 = `query/${expectedName1}/${path1}`
       const expectedQuery1Name = `${operationPart1}`
       const operationPart2 = `mutation/${ANON_PLACEHOLDER}/addThing`
       const expectedQuery2Name = `${operationPart2}`
@@ -565,7 +519,6 @@ function createKoaSegmentsTests(t, frameworkName) {
     const invalidQuery = `query {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
@@ -573,10 +526,10 @@ function createKoaSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books.doesnotexist.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
diff --git a/tests/versioned/apollo-server-lambda/attributes-tests.js b/tests/versioned/apollo-server-lambda/attributes-tests.js
index 811268d..1d8897b 100644
--- a/tests/versioned/apollo-server-lambda/attributes-tests.js
+++ b/tests/versioned/apollo-server-lambda/attributes-tests.js
@@ -40,8 +40,7 @@ function createAttributesTests(t) {
       const operationSegment = findSegmentByName(transaction.trace.root, operationName)
 
       const expectedOperationAttributes = {
-        'graphql.operation.type': 'query',
-        'graphql.operation.deepestPath': 'hello'
+        'graphql.operation.type': 'query'
       }
 
       const operationAttributes = operationSegment.attributes.get(SEGMENT_DESTINATION)
@@ -94,8 +93,7 @@ function createAttributesTests(t) {
 
       const expectedOperationAttributes = {
         'graphql.operation.type': 'query',
-        'graphql.operation.name': expectedName,
-        'graphql.operation.deepestPath': 'hello'
+        'graphql.operation.name': expectedName
       }
 
       const operationAttributes = operationSegment.attributes.get(SEGMENT_DESTINATION)
@@ -131,7 +129,7 @@ function createAttributesTests(t) {
     })
   })
 
-  t.test('named query, multi-level, should capture deepest path', (t) => {
+  t.test('named query, multi-level, should capture deepest unique path', (t) => {
     const { helper, patchedHandler, stubContext, modVersion } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -146,16 +144,15 @@ function createAttributesTests(t) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationName = `${OPERATION_PREFIX}/query/${expectedName}/${deepestPath}`
+      const operationName = `${OPERATION_PREFIX}/query/${expectedName}/${path}`
       const operationSegment = findSegmentByName(transaction.trace.root, operationName)
 
       const expectedOperationAttributes = {
         'graphql.operation.type': 'query',
-        'graphql.operation.name': expectedName,
-        'graphql.operation.deepestPath': deepestPath
+        'graphql.operation.name': expectedName
       }
 
       const operationAttributes = operationSegment.attributes.get(SEGMENT_DESTINATION)
@@ -222,8 +219,7 @@ function createAttributesTests(t) {
 
       const expectedOperationAttributes = {
         'graphql.operation.type': 'mutation',
-        'graphql.operation.name': expectedName,
-        'graphql.operation.deepestPath': 'addThing'
+        'graphql.operation.name': expectedName
       }
 
       const operationAttributes = operationSegment.attributes.get(SEGMENT_DESTINATION)
diff --git a/tests/versioned/apollo-server-lambda/errors-tests.js b/tests/versioned/apollo-server-lambda/errors-tests.js
index 15b9319..c600e85 100644
--- a/tests/versioned/apollo-server-lambda/errors-tests.js
+++ b/tests/versioned/apollo-server-lambda/errors-tests.js
@@ -79,7 +79,6 @@ function createErrorTests(t) {
     const invalidQuery = `query {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
diff --git a/tests/versioned/apollo-server-lambda/segments.test.js b/tests/versioned/apollo-server-lambda/segments.test.js
index f2371e5..94fb059 100644
--- a/tests/versioned/apollo-server-lambda/segments.test.js
+++ b/tests/versioned/apollo-server-lambda/segments.test.js
@@ -98,7 +98,6 @@ function createLambdaSegmentsTests(t, frameworkName) {
     const query = `query {
       libraries {
         books {
-          title
           author {
             name
           }
@@ -106,10 +105,10 @@ function createLambdaSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books.author.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -135,7 +134,7 @@ function createLambdaSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level should return deepest path', (t) => {
+  t.test('named query, multi-level should return deepest unique path', (t) => {
     const { helper, patchedHandler, stubContext, modVersion } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -150,10 +149,10 @@ function createLambdaSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -180,49 +179,6 @@ function createLambdaSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level, should choose *first* deepest-path', (t) => {
-    const { helper, patchedHandler, stubContext, modVersion } = t.context
-
-    const expectedName = 'GetBooksByLibrary'
-    const query = `query ${expectedName} {
-      libraries {
-        books {
-          title
-          isbn
-        }
-      }
-    }`
-
-    // .isbn is the same length but title will be first so that path should be used
-    const firstDeepestPath = 'libraries.books.title'
-
-    helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${firstDeepestPath}`
-      const expectedSegments = [{
-        name: `${TRANSACTION_PREFIX}//${operationPart}`,
-          children: [{
-            name: `${OPERATION_PREFIX}/${operationPart}`,
-            children: [
-              { name: `${RESOLVE_PREFIX}/libraries` },
-              { name: `${RESOLVE_PREFIX}/libraries.books` },
-              { name: `${RESOLVE_PREFIX}/libraries.books.title` },
-              { name: `${RESOLVE_PREFIX}/libraries.books.isbn` }
-            ]
-          }]
-      }]
-
-      t.segments(transaction.trace.root, expectedSegments)
-    })
-
-    executeQueryAssertResult({
-      handler: patchedHandler,
-      query,
-      context: stubContext,
-      t,
-      modVersion
-    })
-  })
-
   t.test('anonymous mutation, single level', (t) => {
     const { helper, patchedHandler, stubContext, modVersion } = t.context
 
@@ -376,10 +332,10 @@ function createLambdaSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -433,12 +389,12 @@ function createLambdaSegmentsTests(t, frameworkName) {
       addThing(name: "added thing!")
     }`
 
-    const deepestPath1 = 'library.books.author.name'
+    const path1 = 'library.books'
 
     const queries = [query1, query2]
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart1 = `query/${expectedName1}/${deepestPath1}`
+      const operationPart1 = `query/${expectedName1}/${path1}`
       const expectedQuery1Name = `${operationPart1}`
       const operationPart2 = `mutation/${ANON_PLACEHOLDER}/addThing`
       const expectedQuery2Name = `${operationPart2}`
@@ -537,7 +493,6 @@ function createLambdaSegmentsTests(t, frameworkName) {
     const invalidQuery = `query {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
@@ -545,10 +500,10 @@ function createLambdaSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books.doesnotexist.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -569,4 +524,3 @@ function createLambdaSegmentsTests(t, frameworkName) {
     })
   })
 }
-
diff --git a/tests/versioned/apollo-server-lambda/transaction-naming-tests.js b/tests/versioned/apollo-server-lambda/transaction-naming-tests.js
index 09b2fa8..9c33daf 100644
--- a/tests/versioned/apollo-server-lambda/transaction-naming-tests.js
+++ b/tests/versioned/apollo-server-lambda/transaction-naming-tests.js
@@ -73,7 +73,7 @@ function createTransactionTests(t, frameworkName) {
     })
   })
 
-  t.test('anonymous query, multi-level should return deepest path', (t) => {
+  t.test('anonymous query, multi-level should return deepest unique path', (t) => {
     const { helper, patchedHandler, stubContext, modVersion } = t.context
 
     const query = `query {
@@ -87,12 +87,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${ANON_PLACEHOLDER}/${deepestPath}`
+        `${EXPECTED_PREFIX}//query/${ANON_PLACEHOLDER}/${path}`
       )
     })
 
@@ -105,7 +105,7 @@ function createTransactionTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level should return deepest path', (t) => {
+  t.test('named query, multi-level should return deepest unique path', (t) => {
     const { helper, patchedHandler, stubContext, modVersion } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -120,44 +120,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${expectedName}/${deepestPath}`
-      )
-    })
-
-    executeQueryAssertResult({
-      handler: patchedHandler,
-      query,
-      context: stubContext,
-      modVersion,
-      t
-    })
-  })
-
-  t.test('named query, multi-level, should choose *first* deepest-path', (t) => {
-    const { helper, patchedHandler, stubContext, modVersion } = t.context
-
-    const expectedName = 'GetBooksByLibrary'
-    const query = `query ${expectedName} {
-      libraries {
-        books {
-          title
-          isbn
-        }
-      }
-    }`
-
-    // .isbn is the same length but title will be first so that path should be used
-    const firstDeepestPath = 'libraries.books.title'
-
-    helper.agent.on('transactionFinished', (transaction) => {
-      t.equal(
-        transaction.name,
-        `${EXPECTED_PREFIX}//query/${expectedName}/${firstDeepestPath}`
+        `${EXPECTED_PREFIX}//query/${expectedName}/${path}`
       )
     })
 
@@ -264,7 +232,7 @@ function createTransactionTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, with params, should return deepest path', (t) => {
+  t.test('named query, with params, should return deepest unique path', (t) => {
     const { helper, patchedHandler, stubContext, modVersion } = t.context
 
     const expectedName = 'GetBookForLibrary'
@@ -279,12 +247,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${expectedName}/${deepestPath}`
+        `${EXPECTED_PREFIX}//query/${expectedName}/${path}`
       )
     })
 
@@ -316,12 +284,12 @@ function createTransactionTests(t, frameworkName) {
       addThing(name: "added thing!")
     }`
 
-    const DeepestPath1 = 'library.books.author.name'
+    const path = 'library.books'
 
     const queries = [query1, query2]
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const expectedQuery1Name = `query/${expectedName1}/${DeepestPath1}`
+      const expectedQuery1Name = `query/${expectedName1}/${path}`
       const expectedQuery2Name = `mutation/${ANON_PLACEHOLDER}/addThing`
       t.equal(
         transaction.name,
@@ -380,7 +348,6 @@ function createTransactionTests(t, frameworkName) {
     const invalidQuery = `query {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
@@ -388,12 +355,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books.doesnotexist.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${ANON_PLACEHOLDER}/${deepestPath}`
+        `${EXPECTED_PREFIX}//query/${ANON_PLACEHOLDER}/${path}`
       )
     })
 
@@ -416,7 +383,6 @@ function createTransactionTests(t, frameworkName) {
     const invalidQuery = `query ${expectedName} {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
@@ -424,12 +390,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books.doesnotexist.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${expectedName}/${deepestPath}`
+        `${EXPECTED_PREFIX}//query/${expectedName}/${path}`
       )
     })
 
@@ -443,4 +409,3 @@ function createTransactionTests(t, frameworkName) {
     })
   })
 }
-
diff --git a/tests/versioned/attributes-tests.js b/tests/versioned/attributes-tests.js
index 7e6271b..daf5dd0 100644
--- a/tests/versioned/attributes-tests.js
+++ b/tests/versioned/attributes-tests.js
@@ -33,8 +33,7 @@ function createAttributesTests(t) {
       const operationSegment = findSegmentByName(transaction.trace.root, operationName)
 
       const expectedOperationAttributes = {
-        'graphql.operation.type': 'query',
-        'graphql.operation.deepestPath': 'hello'
+        'graphql.operation.type': 'query'
       }
 
       const operationAttributes = operationSegment.attributes.get(SEGMENT_DESTINATION)
@@ -84,8 +83,7 @@ function createAttributesTests(t) {
 
       const expectedOperationAttributes = {
         'graphql.operation.type': 'query',
-        'graphql.operation.name': expectedName,
-        'graphql.operation.deepestPath': 'hello'
+        'graphql.operation.name': expectedName
       }
 
       const operationAttributes = operationSegment.attributes.get(SEGMENT_DESTINATION)
@@ -118,7 +116,7 @@ function createAttributesTests(t) {
     })
   })
 
-  t.test('named query, multi-level, should capture deepest path', (t) => {
+  t.test('named query, multi-level, should capture deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -133,7 +131,7 @@ function createAttributesTests(t) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const deepestPath = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
       const operationName = `${OPERATION_PREFIX}/query/${expectedName}/${deepestPath}`
@@ -141,8 +139,7 @@ function createAttributesTests(t) {
 
       const expectedOperationAttributes = {
         'graphql.operation.type': 'query',
-        'graphql.operation.name': expectedName,
-        'graphql.operation.deepestPath': deepestPath
+        'graphql.operation.name': expectedName
       }
 
       const operationAttributes = operationSegment.attributes.get(SEGMENT_DESTINATION)
@@ -206,8 +203,7 @@ function createAttributesTests(t) {
 
       const expectedOperationAttributes = {
         'graphql.operation.type': 'mutation',
-        'graphql.operation.name': expectedName,
-        'graphql.operation.deepestPath': 'addThing'
+        'graphql.operation.name': expectedName
       }
 
       const operationAttributes = operationSegment.attributes.get(SEGMENT_DESTINATION)
diff --git a/tests/versioned/errors-tests.js b/tests/versioned/errors-tests.js
index 179686c..33dc452 100644
--- a/tests/versioned/errors-tests.js
+++ b/tests/versioned/errors-tests.js
@@ -84,7 +84,6 @@ function createErrorTests(t) {
     const invalidQuery = `query {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
diff --git a/tests/versioned/express-segments-default-tests.js b/tests/versioned/express-segments-default-tests.js
index 0e3a5d0..5419208 100644
--- a/tests/versioned/express-segments-default-tests.js
+++ b/tests/versioned/express-segments-default-tests.js
@@ -102,7 +102,6 @@ function createSegmentsTests(t, frameworkName) {
     const query = `query {
       libraries {
         books {
-          title
           author {
             name
           }
@@ -110,10 +109,10 @@ function createSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books.author.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -143,7 +142,7 @@ function createSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level should return deepest path', (t) => {
+  t.test('named query, multi-level should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -158,10 +157,10 @@ function createSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -191,52 +190,6 @@ function createSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level, should choose *first* deepest-path', (t) => {
-    const { helper, serverUrl } = t.context
-
-    const expectedName = 'GetBooksByLibrary'
-    const query = `query ${expectedName} {
-      libraries {
-        books {
-          title
-          isbn
-        }
-      }
-    }`
-
-    // .isbn is the same length but title will be first so that path should be used
-    const firstDeepestPath = 'libraries.books.title'
-
-    helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${firstDeepestPath}`
-      const expectedSegments = [{
-        name: `${TRANSACTION_PREFIX}//${operationPart}`,
-        children: [{
-          name: 'Expressjs/Router: /',
-          children: [{
-            name: 'Nodejs/Middleware/Expressjs/<anonymous>',
-            children: [{
-              name: `${OPERATION_PREFIX}/${operationPart}`,
-              children: [
-                { name: `${RESOLVE_PREFIX}/libraries` },
-                { name: `${RESOLVE_PREFIX}/libraries.books` }
-              ]
-            }]
-          }]
-        }]
-      }]
-
-      t.segments(transaction.trace.root, expectedSegments)
-    })
-
-    executeQuery(serverUrl, query, (err, result) => {
-      t.error(err)
-      checkResult(t, result, () => {
-        t.end()
-      })
-    })
-  })
-
   t.test('anonymous mutation, single level', (t) => {
     const { helper, serverUrl } = t.context
 
@@ -402,7 +355,6 @@ function createSegmentsTests(t, frameworkName) {
     const query = `query ${expectedName} {
       library(branch: "downtown") {
         books {
-          title
           author {
             name
           }
@@ -410,10 +362,10 @@ function createSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library.books.author.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -470,12 +422,12 @@ function createSegmentsTests(t, frameworkName) {
       addThing(name: "added thing!")
     }`
 
-    const deepestPath1 = 'library.books.author.name'
+    const path1 = 'library.books'
 
     const queries = [query1, query2]
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart1 = `query/${expectedName1}/${deepestPath1}`
+      const operationPart1 = `query/${expectedName1}/${path1}`
       const expectedQuery1Name = `${operationPart1}`
       const operationPart2 = `mutation/${ANON_PLACEHOLDER}/addThing`
       const expectedQuery2Name = `${operationPart2}`
@@ -589,7 +541,6 @@ function createSegmentsTests(t, frameworkName) {
     const invalidQuery = `query {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
@@ -597,10 +548,10 @@ function createSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books.doesnotexist.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
diff --git a/tests/versioned/express-segments-scalar-tests.js b/tests/versioned/express-segments-scalar-tests.js
index 100a336..6f5cfca 100644
--- a/tests/versioned/express-segments-scalar-tests.js
+++ b/tests/versioned/express-segments-scalar-tests.js
@@ -110,10 +110,10 @@ function createSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -144,7 +144,7 @@ function createSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level should return deepest path', (t) => {
+  t.test('named query, multi-level should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -159,10 +159,10 @@ function createSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -194,54 +194,6 @@ function createSegmentsTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level, should choose *first* deepest-path', (t) => {
-    const { helper, serverUrl } = t.context
-
-    const expectedName = 'GetBooksByLibrary'
-    const query = `query ${expectedName} {
-      libraries {
-        books {
-          title
-          isbn
-        }
-      }
-    }`
-
-    // .isbn is the same length but title will be first so that path should be used
-    const firstDeepestPath = 'libraries.books.title'
-
-    helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${firstDeepestPath}`
-      const expectedSegments = [{
-        name: `${TRANSACTION_PREFIX}//${operationPart}`,
-        children: [{
-          name: 'Expressjs/Router: /',
-          children: [{
-            name: 'Nodejs/Middleware/Expressjs/<anonymous>',
-            children: [{
-              name: `${OPERATION_PREFIX}/${operationPart}`,
-              children: [
-                { name: `${RESOLVE_PREFIX}/libraries` },
-                { name: `${RESOLVE_PREFIX}/libraries.books` },
-                { name: `${RESOLVE_PREFIX}/libraries.books.title` },
-                { name: `${RESOLVE_PREFIX}/libraries.books.isbn` }
-              ]
-            }]
-          }]
-        }]
-      }]
-
-      t.segments(transaction.trace.root, expectedSegments)
-    })
-
-    executeQuery(serverUrl, query, (err, result) => {
-      t.error(err)
-      checkResult(t, result, () => {
-        t.end()
-      })
-    })
-  })
-
   t.test('anonymous mutation, single level', (t) => {
     const { helper, serverUrl } = t.context
 
@@ -415,10 +367,10 @@ function createSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${expectedName}/${deepestPath}`
+      const operationPart = `query/${expectedName}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
@@ -477,12 +429,12 @@ function createSegmentsTests(t, frameworkName) {
       addThing(name: "added thing!")
     }`
 
-    const deepestPath1 = 'library.books.author.name'
+    const path1 = 'library.books'
 
     const queries = [query1, query2]
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart1 = `query/${expectedName1}/${deepestPath1}`
+      const operationPart1 = `query/${expectedName1}/${path1}`
       const expectedQuery1Name = `${operationPart1}`
       const operationPart2 = `mutation/${ANON_PLACEHOLDER}/addThing`
       const expectedQuery2Name = `${operationPart2}`
@@ -606,10 +558,10 @@ function createSegmentsTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const operationPart = `query/${ANON_PLACEHOLDER}/${deepestPath}`
+      const operationPart = `query/${ANON_PLACEHOLDER}/${path}`
       const expectedSegments = [{
         name: `${TRANSACTION_PREFIX}//${operationPart}`,
         children: [{
diff --git a/tests/versioned/transaction-naming-tests.js b/tests/versioned/transaction-naming-tests.js
index 11317b6..1c94336 100644
--- a/tests/versioned/transaction-naming-tests.js
+++ b/tests/versioned/transaction-naming-tests.js
@@ -64,7 +64,7 @@ function createTransactionTests(t, frameworkName) {
     })
   })
 
-  t.test('anonymous query, multi-level should return deepest path', (t) => {
+  t.test('anonymous query, multi-level should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const query = `query {
@@ -78,12 +78,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${ANON_PLACEHOLDER}/${deepestPath}`
+        `${EXPECTED_PREFIX}//query/${ANON_PLACEHOLDER}/${path}`
       )
     })
 
@@ -95,7 +95,7 @@ function createTransactionTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, multi-level should return deepest path', (t) => {
+  t.test('named query, multi-level should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const expectedName = 'GetBooksByLibrary'
@@ -110,43 +110,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.author.name'
+    const path = 'libraries.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${expectedName}/${deepestPath}`
-      )
-    })
-
-    executeQuery(serverUrl, query, (err, result) => {
-      t.error(err)
-      checkResult(t, result, () => {
-        t.end()
-      })
-    })
-  })
-
-  t.test('named query, multi-level, should choose *first* deepest-path', (t) => {
-    const { helper, serverUrl } = t.context
-
-    const expectedName = 'GetBooksByLibrary'
-    const query = `query ${expectedName} {
-      libraries {
-        books {
-          title
-          isbn
-        }
-      }
-    }`
-
-    // .isbn is the same length but title will be first so that path should be used
-    const firstDeepestPath = 'libraries.books.title'
-
-    helper.agent.on('transactionFinished', (transaction) => {
-      t.equal(
-        transaction.name,
-        `${EXPECTED_PREFIX}//query/${expectedName}/${firstDeepestPath}`
+        `${EXPECTED_PREFIX}//query/${expectedName}/${path}`
       )
     })
 
@@ -248,7 +217,7 @@ function createTransactionTests(t, frameworkName) {
     })
   })
 
-  t.test('named query, with params, should return deepest path', (t) => {
+  t.test('named query, with params, should return deepest unique path', (t) => {
     const { helper, serverUrl } = t.context
 
     const expectedName = 'GetBookForLibrary'
@@ -263,12 +232,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'library.books.author.name'
+    const path = 'library.books'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${expectedName}/${deepestPath}`
+        `${EXPECTED_PREFIX}//query/${expectedName}/${path}`
       )
     })
 
@@ -299,12 +268,12 @@ function createTransactionTests(t, frameworkName) {
       addThing(name: "added thing!")
     }`
 
-    const DeepestPath1 = 'library.books.author.name'
+    const path1 = 'library.books'
 
     const queries = [query1, query2]
 
     helper.agent.on('transactionFinished', (transaction) => {
-      const expectedQuery1Name = `query/${expectedName1}/${DeepestPath1}`
+      const expectedQuery1Name = `query/${expectedName1}/${path1}`
       const expectedQuery2Name = `mutation/${ANON_PLACEHOLDER}/addThing`
       t.equal(
         transaction.name,
@@ -363,7 +332,6 @@ function createTransactionTests(t, frameworkName) {
     const invalidQuery = `query {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
@@ -371,12 +339,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books.doesnotexist.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${ANON_PLACEHOLDER}/${deepestPath}`
+        `${EXPECTED_PREFIX}//query/${ANON_PLACEHOLDER}/${path}`
       )
     })
 
@@ -403,7 +371,6 @@ function createTransactionTests(t, frameworkName) {
     const invalidQuery = `query ${expectedName} {
       libraries {
         books {
-          title
           doesnotexist {
             name
           }
@@ -411,12 +378,12 @@ function createTransactionTests(t, frameworkName) {
       }
     }`
 
-    const deepestPath = 'libraries.books.doesnotexist.name'
+    const path = 'libraries.books.doesnotexist.name'
 
     helper.agent.on('transactionFinished', (transaction) => {
       t.equal(
         transaction.name,
-        `${EXPECTED_PREFIX}//query/${expectedName}/${deepestPath}`
+        `${EXPECTED_PREFIX}//query/${expectedName}/${path}`
       )
     })