nodes: 0, module; 1, function_definition; 2, function_name:get_properties_by_type; 3, parameters; 4, block; 5, identifier:self; 6, identifier:type; 7, default_parameter; 8, default_parameter; 9, expression_statement; 10, if_statement; 11, if_statement; 12, expression_statement; 13, for_statement; 14, return_statement; 15, identifier:recursive; 16, True; 17, identifier:parent_path; 18, string:""; 19, comment:"""
          Returns a sorted list of fields that match the type.
  
          :param type the type of the field "string","integer" or a list of types
          :param recursive recurse to sub object
          :returns a sorted list of fields the match the type
  
          """; 20, identifier:parent_path; 21, block; 22, call; 23, block; 24, assignment; 25, identifier:prop; 26, call; 27, block; 28, call; 29, expression_statement; 30, identifier:isinstance; 31, argument_list; 32, if_statement; 33, identifier:properties; 34, list; 35, identifier:list; 36, argument_list; 37, if_statement; 38, if_statement; 39, if_statement; 40, identifier:sorted; 41, argument_list; 42, augmented_assignment; 43, identifier:type; 44, identifier:str; 45, comparison_operator:type == "*"; 46, block; 47, else_clause; 48, call; 49, comparison_operator:prop.type in type; 50, block; 51, elif_clause; 52, not_operator; 53, block; 54, comparison_operator:prop.type in ["nested", "object"]; 55, block; 56, identifier:properties; 57, identifier:parent_path; 58, string:"."; 59, identifier:type; 60, string:"*"; 61, expression_statement; 62, block; 63, attribute; 64, argument_list; 65, attribute; 66, identifier:type; 67, expression_statement; 68, continue_statement; 69, boolean_operator; 70, block; 71, identifier:recursive; 72, continue_statement; 73, attribute; 74, list; 75, expression_statement; 76, assignment; 77, expression_statement; 78, attribute; 79, identifier:values; 80, identifier:prop; 81, identifier:type; 82, call; 83, boolean_operator; 84, comparison_operator:prop.fields[prop.name].type in type; 85, expression_statement; 86, continue_statement; 87, identifier:prop; 88, identifier:type; 89, string:"nested"; 90, string:"object"; 91, call; 92, identifier:type; 93, binary_operator:set(MAPPING_NAME_TYPE.keys()) - set(["nested", "multi_field", "multifield"]); 94, assignment; 95, identifier:self; 96, identifier:properties; 97, attribute; 98, argument_list; 99, comparison_operator:prop.type == "multi_field"; 100, comparison_operator:prop.name in prop.fields; 101, attribute; 102, identifier:type; 103, call; 104, attribute; 105, argument_list; 106, call; 107, call; 108, identifier:type; 109, list; 110, identifier:properties; 111, identifier:append; 112, tuple; 113, attribute; 114, string:"multi_field"; 115, attribute; 116, attribute; 117, subscript; 118, identifier:type; 119, attribute; 120, argument_list; 121, identifier:properties; 122, identifier:extend; 123, call; 124, identifier:set; 125, argument_list; 126, identifier:set; 127, argument_list; 128, identifier:type; 129, binary_operator:parent_path + prop.name; 130, identifier:prop; 131, identifier:prop; 132, identifier:type; 133, identifier:prop; 134, identifier:name; 135, identifier:prop; 136, identifier:fields; 137, attribute; 138, attribute; 139, identifier:properties; 140, identifier:append; 141, tuple; 142, attribute; 143, argument_list; 144, call; 145, list; 146, identifier:parent_path; 147, attribute; 148, identifier:prop; 149, identifier:fields; 150, identifier:prop; 151, identifier:name; 152, binary_operator:parent_path + prop.name; 153, identifier:prop; 154, identifier:prop; 155, identifier:get_properties_by_type; 156, identifier:type; 157, keyword_argument; 158, keyword_argument; 159, attribute; 160, argument_list; 161, string:"nested"; 162, string:"multi_field"; 163, string:"multifield"; 164, identifier:prop; 165, identifier:name; 166, identifier:parent_path; 167, attribute; 168, identifier:recursive; 169, identifier:recursive; 170, identifier:parent_path; 171, binary_operator:parent_path + prop.name; 172, identifier:MAPPING_NAME_TYPE; 173, identifier:keys; 174, identifier:prop; 175, identifier:name; 176, identifier:parent_path; 177, attribute; 178, identifier:prop; 179, identifier:name
code: def get_properties_by_type(self, type, recursive=True, parent_path=""):
          """
          Returns a sorted list of fields that match the type.
  
          :param type the type of the field "string","integer" or a list of types
          :param recursive recurse to sub object
          :returns a sorted list of fields the match the type
  
          """
          if parent_path:
              parent_path += "."
  
          if isinstance(type, str):
              if type == "*":
                  type = set(MAPPING_NAME_TYPE.keys()) - set(["nested", "multi_field", "multifield"])
              else:
                  type = [type]
          properties = []
          for prop in list(self.properties.values()):
              if prop.type in type:
                  properties.append((parent_path + prop.name, prop))
                  continue
              elif prop.type == "multi_field" and prop.name in prop.fields and prop.fields[prop.name].type in type:
                  properties.append((parent_path + prop.name, prop))
                  continue
  
              if not recursive:
                  continue
              if prop.type in ["nested", "object"]:
                  properties.extend(
                      prop.get_properties_by_type(type, recursive=recursive, parent_path=parent_path + prop.name))
          return sorted(properties)