code: private void convertToTermsQuery(FilterJoinNode node) {
      Map<String, Object> parent = node.getParentSourceMap();
      FilterJoinTerms terms = node.getTerms();
      BytesRef bytes = terms.getEncodedTerms();
  
      // Remove the filter join from the parent
      parent.remove(FilterJoinBuilder.NAME);
  
      // Create the nested object for the parameters of the field data terms query
      Map<String, Object> queryParams = new HashMap<>();
      queryParams.put("value", bytes.bytes);
      // use the hash of the filter join source map as cache key - see #170
      queryParams.put("_cache_key", node.getCacheId());
  
      // Create the nested object for the field
      Map<String, Object> field = new HashMap<>();
      field.put(node.getField(), queryParams);
  
      // Create the nested object for the field data terms query
      Map<String, Object> termsQuery = new HashMap<>();
      // If bytes terms encoding is used, we switch to the terms enum based terms query
      if (node.getTermsEncoding().equals(TermsByQueryRequest.TermsEncoding.BYTES)) {
        termsQuery.put(TermsEnumTermsQueryParser.NAME, field);
      }
      else {
        termsQuery.put(FieldDataTermsQueryParser.NAME, field);
      }
  
      // Create the object for the constant score query
      Map<String, Object> constantScoreQueryParams = new HashMap<>();
      constantScoreQueryParams.put("filter", termsQuery);
  
      // Add the constant score query to the parent
      parent.put(ConstantScoreQueryParser.NAME, constantScoreQueryParams);
      node.setState(FilterJoinNode.State.CONVERTED);
      this.blockingQueue.poll();
    }
docs: Converts a filter join into a terms query.