private ISearchField getProjectionField(ParseQueryNode projectNode) {
    if (nodeProjectField.containsKey(projectNode)) {
      return nodeProjectField.get(projectNode);
    }

    ISearchField field = null;
    // make sure the sub-query has only one user projection
    Collection<ISearchField> searchFields = projectNode.getUserProjection().getFields();
    boolean noUserSpecifyProject =
        projectNode.getUserProjection().hasStar() || projectNode.getUserProjection().isEmpty();
    if (noUserSpecifyProject) {
      if (isTargetReference) {
        // use the _oid when not specific user projection given for target reference. _oid is the
        // mandatory internal project
        searchFields.add(
            new ProjectionField(
                projectNode.getMetaClass().getFieldByName(InternalFieldEnum.ID.getName()),
                true,
                queryContext.getRegistration().searchStrategy));
      } else {
        searchFields = projectNode.getProjection().getFields();
      }
    }

    if (searchFields.size() > 1) {
      throw new QueryExecuteException(
          QueryErrCodeEnum.IILEGAL_PROJECTION,
          MessageFormat.format(
              "sub query could only have one root projection, but actually get {0} fields!",
              searchFields.size()));
    }
    field = searchFields.iterator().next();
    nodeProjectField.put(projectNode, field);
    return field;
  }
 static boolean isRelationshipField(ISearchField field) {
   if (AbstractSearchField.class.isInstance(field)) {
     AbstractSearchField selection = (AbstractSearchField) field;
     return selection.getRootField().getDataType().equals(DataTypeEnum.RELATIONSHIP)
         && (selection.getInnerField() == null
             || selection.getInnerField().equals(InternalFieldEnum.ID.getDbName()));
   }
   return false;
 }
  @Override
  public boolean isIndexUsable(ISearchField field, MetaClass metaClass) {
    Collection<IndexInfo> indexes = metaClass.getIndexesOnField(field.getFieldName());
    for (IndexInfo index : indexes) {
      String firstKey = index.getKeyList().get(0);
      MetaField metaField = metaClass.getFieldByName(firstKey);

      String physicalKeyName = getFieldValueName(metaField);
      if (metaField.getDataType().equals(DataTypeEnum.RELATIONSHIP)) {
        physicalKeyName =
            metaField.getFlattenValueDbName()
                + AbstractEntityIDHelper.DOT
                + InternalFieldEnum.ID.getDbName();
      }
      if (physicalKeyName.equals(field.getFullDbName())) {
        return true;
      }
    }
    return false;
  }