Пример #1
0
    @Override
    public OntologyMapper build(BuilderContext context) {
      ContentPath.Type origPathType = context.path().pathType();
      context.path().pathType(pathType);

      Map<String, FieldMapper<String>> fieldMappers = Maps.newHashMap();

      context.path().add(name);

      if (propertyBuilders != null) {
        for (String property : propertyBuilders.keySet()) {
          StringFieldMapper sfm = propertyBuilders.get(property).build(context);
          fieldMappers.put(sfm.names().indexName(), sfm);
        }
      }

      // Initialise field mappers for the pre-defined fields
      for (FieldMappings mapping : ontologySettings.getFieldMappings()) {
        if (!fieldMappers.containsKey(context.path().fullPathAsText(mapping.getFieldName()))) {
          StringFieldMapper mapper =
              MapperBuilders.stringField(mapping.getFieldName())
                  .store(true)
                  .index(true)
                  .tokenized(!mapping.isUriField())
                  .build(context);
          fieldMappers.put(mapper.names().indexName(), mapper);
        }
      }

      context.path().remove(); // remove name
      context.path().pathType(origPathType);

      return new OntologyMapper(
          buildNames(context),
          fieldType,
          docValues,
          indexAnalyzer,
          searchAnalyzer,
          postingsProvider,
          docValuesProvider,
          similarity,
          fieldDataSettings,
          context.indexSettings(),
          new MultiFields.Builder().build(this, context),
          ontologySettings,
          fieldMappers,
          threadPool);
    }
 public <IFD extends IndexFieldData<?>> IFD getForField(FieldDataType type, String fieldName) {
   final FieldMapper<?> mapper;
   final BuilderContext context = new BuilderContext(null, new ContentPath(1));
   if (type.getType().equals("string")) {
     mapper =
         MapperBuilders.stringField(fieldName)
             .tokenized(false)
             .fieldDataSettings(type.getSettings())
             .build(context);
   } else if (type.getType().equals("float")) {
     mapper =
         MapperBuilders.floatField(fieldName).fieldDataSettings(type.getSettings()).build(context);
   } else if (type.getType().equals("double")) {
     mapper =
         MapperBuilders.doubleField(fieldName)
             .fieldDataSettings(type.getSettings())
             .build(context);
   } else if (type.getType().equals("long")) {
     mapper =
         MapperBuilders.longField(fieldName).fieldDataSettings(type.getSettings()).build(context);
   } else if (type.getType().equals("int")) {
     mapper =
         MapperBuilders.integerField(fieldName)
             .fieldDataSettings(type.getSettings())
             .build(context);
   } else if (type.getType().equals("short")) {
     mapper =
         MapperBuilders.shortField(fieldName).fieldDataSettings(type.getSettings()).build(context);
   } else if (type.getType().equals("byte")) {
     mapper =
         MapperBuilders.byteField(fieldName).fieldDataSettings(type.getSettings()).build(context);
   } else if (type.getType().equals("geo_point")) {
     mapper =
         MapperBuilders.geoPointField(fieldName)
             .fieldDataSettings(type.getSettings())
             .build(context);
   } else if (type.getType().equals("_parent")) {
     mapper = MapperBuilders.parent().type(fieldName).build(context);
   } else if (type.getType().equals("binary")) {
     mapper =
         MapperBuilders.binaryField(fieldName)
             .fieldDataSettings(type.getSettings())
             .build(context);
   } else {
     throw new UnsupportedOperationException(type.getType());
   }
   return ifdService.getForField(mapper);
 }
 private static Mapper.Builder<?, ?> createBuilderFromFieldType(
     final ParseContext context, MappedFieldType fieldType, String currentFieldName) {
   Mapper.Builder builder = null;
   if (fieldType instanceof StringFieldType) {
     builder = context.root().findTemplateBuilder(context, currentFieldName, "string");
     if (builder == null) {
       builder = MapperBuilders.stringField(currentFieldName);
     }
   } else if (fieldType instanceof DateFieldType) {
     builder = context.root().findTemplateBuilder(context, currentFieldName, "date");
     if (builder == null) {
       builder = MapperBuilders.dateField(currentFieldName);
     }
   } else if (fieldType.numericType() != null) {
     switch (fieldType.numericType()) {
       case LONG:
         builder = context.root().findTemplateBuilder(context, currentFieldName, "long");
         if (builder == null) {
           builder = MapperBuilders.longField(currentFieldName);
         }
         break;
       case DOUBLE:
         builder = context.root().findTemplateBuilder(context, currentFieldName, "double");
         if (builder == null) {
           builder = MapperBuilders.doubleField(currentFieldName);
         }
         break;
       case INT:
         builder = context.root().findTemplateBuilder(context, currentFieldName, "integer");
         if (builder == null) {
           builder = MapperBuilders.integerField(currentFieldName);
         }
         break;
       case FLOAT:
         builder = context.root().findTemplateBuilder(context, currentFieldName, "float");
         if (builder == null) {
           builder = MapperBuilders.floatField(currentFieldName);
         }
         break;
       default:
         throw new AssertionError("Unexpected numeric type " + fieldType.numericType());
     }
   }
   return builder;
 }
  private static Mapper.Builder<?, ?> createBuilderFromDynamicValue(
      final ParseContext context, XContentParser.Token token, String currentFieldName)
      throws IOException {
    if (token == XContentParser.Token.VALUE_STRING) {
      // do a quick test to see if its fits a dynamic template, if so, use it.
      // we need to do it here so we can handle things like attachment templates, where calling
      // text (to see if its a date) causes the binary value to be cleared
      {
        Mapper.Builder builder =
            context.root().findTemplateBuilder(context, currentFieldName, "string", null);
        if (builder != null) {
          return builder;
        }
      }

      if (context.root().dateDetection()) {
        String text = context.parser().text();
        // a safe check since "1" gets parsed as well
        if (Strings.countOccurrencesOf(text, ":") > 1
            || Strings.countOccurrencesOf(text, "-") > 1
            || Strings.countOccurrencesOf(text, "/") > 1) {
          for (FormatDateTimeFormatter dateTimeFormatter :
              context.root().dynamicDateTimeFormatters()) {
            try {
              dateTimeFormatter.parser().parseMillis(text);
              Mapper.Builder builder =
                  context.root().findTemplateBuilder(context, currentFieldName, "date");
              if (builder == null) {
                builder =
                    MapperBuilders.dateField(currentFieldName).dateTimeFormatter(dateTimeFormatter);
              }
              return builder;
            } catch (Exception e) {
              // failure to parse this, continue
            }
          }
        }
      }
      if (context.root().numericDetection()) {
        String text = context.parser().text();
        try {
          Long.parseLong(text);
          Mapper.Builder builder =
              context.root().findTemplateBuilder(context, currentFieldName, "long");
          if (builder == null) {
            builder = MapperBuilders.longField(currentFieldName);
          }
          return builder;
        } catch (NumberFormatException e) {
          // not a long number
        }
        try {
          Double.parseDouble(text);
          Mapper.Builder builder =
              context.root().findTemplateBuilder(context, currentFieldName, "double");
          if (builder == null) {
            builder = MapperBuilders.doubleField(currentFieldName);
          }
          return builder;
        } catch (NumberFormatException e) {
          // not a long number
        }
      }
      Mapper.Builder builder =
          context.root().findTemplateBuilder(context, currentFieldName, "string");
      if (builder == null) {
        builder = MapperBuilders.stringField(currentFieldName);
      }
      return builder;
    } else if (token == XContentParser.Token.VALUE_NUMBER) {
      XContentParser.NumberType numberType = context.parser().numberType();
      if (numberType == XContentParser.NumberType.INT
          || numberType == XContentParser.NumberType.LONG) {
        Mapper.Builder builder =
            context.root().findTemplateBuilder(context, currentFieldName, "long");
        if (builder == null) {
          builder = MapperBuilders.longField(currentFieldName);
        }
        return builder;
      } else if (numberType == XContentParser.NumberType.FLOAT
          || numberType == XContentParser.NumberType.DOUBLE) {
        Mapper.Builder builder =
            context.root().findTemplateBuilder(context, currentFieldName, "double");
        if (builder == null) {
          // no templates are defined, we use float by default instead of double
          // since this is much more space-efficient and should be enough most of
          // the time
          builder = MapperBuilders.floatField(currentFieldName);
        }
        return builder;
      }
    } else if (token == XContentParser.Token.VALUE_BOOLEAN) {
      Mapper.Builder builder =
          context.root().findTemplateBuilder(context, currentFieldName, "boolean");
      if (builder == null) {
        builder = MapperBuilders.booleanField(currentFieldName);
      }
      return builder;
    } else if (token == XContentParser.Token.VALUE_EMBEDDED_OBJECT) {
      Mapper.Builder builder =
          context.root().findTemplateBuilder(context, currentFieldName, "binary");
      if (builder == null) {
        builder = MapperBuilders.binaryField(currentFieldName);
      }
      return builder;
    } else {
      Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, null);
      if (builder != null) {
        return builder;
      }
    }
    // TODO how do we identify dynamically that its a binary value?
    throw new IllegalStateException(
        "Can't handle serializing a dynamic type with content token ["
            + token
            + "] and field name ["
            + currentFieldName
            + "]");
  }
Пример #5
0
  @Override
  public void parse(ParseContext context) throws IOException {
    String iri;
    XContentParser parser = context.parser();
    XContentParser.Token token = parser.currentToken();

    if (token == XContentParser.Token.VALUE_STRING) {
      iri = parser.text();
    } else {
      throw new MapperParsingException(name() + " does not contain String value");
    }

    ContentPath.Type origPathType = context.path().pathType();
    context.path().pathType(ContentPath.Type.FULL);
    context.path().add(names.name());

    try {
      OntologyHelper helper = getHelper(ontologySettings, threadPool);

      OntologyData data = findOntologyData(helper, iri);
      if (data == null) {
        logger.debug("Cannot find OWL class for IRI {}", iri);
      } else {
        addFieldData(
            context,
            getPredefinedMapper(FieldMappings.URI, context),
            Collections.singletonList(iri));

        // Look up the label(s)
        addFieldData(context, getPredefinedMapper(FieldMappings.LABEL, context), data.getLabels());

        // Look up the synonyms
        addFieldData(
            context, getPredefinedMapper(FieldMappings.SYNONYMS, context), data.getLabels());

        // Add the child details
        addRelatedNodesWithLabels(
            context,
            data.getChildIris(),
            getPredefinedMapper(FieldMappings.CHILD_URI, context),
            data.getChildLabels(),
            getPredefinedMapper(FieldMappings.CHILD_LABEL, context));

        // Add the parent details
        addRelatedNodesWithLabels(
            context,
            data.getParentIris(),
            getPredefinedMapper(FieldMappings.PARENT_URI, context),
            data.getParentLabels(),
            getPredefinedMapper(FieldMappings.PARENT_LABEL, context));

        if (ontologySettings.isIncludeIndirect()) {
          // Add the descendant details
          addRelatedNodesWithLabels(
              context,
              data.getDescendantIris(),
              getPredefinedMapper(FieldMappings.DESCENDANT_URI, context),
              data.getDescendantLabels(),
              getPredefinedMapper(FieldMappings.DESCENDANT_LABEL, context));

          // Add the ancestor details
          addRelatedNodesWithLabels(
              context,
              data.getAncestorIris(),
              getPredefinedMapper(FieldMappings.ANCESTOR_URI, context),
              data.getAncestorLabels(),
              getPredefinedMapper(FieldMappings.ANCESTOR_LABEL, context));
        }

        if (ontologySettings.isIncludeRelations()) {
          // Add the related nodes
          Map<String, Collection<String>> relations = data.getRelationIris();

          for (String relation : relations.keySet()) {
            // Sanitise the relation name
            String sanRelation = relation.replaceAll("\\W+", "_");
            String uriMapperName = sanRelation + DYNAMIC_URI_FIELD_SUFFIX;
            String labelMapperName = sanRelation + DYNAMIC_LABEL_FIELD_SUFFIX;

            // Get the mapper for the relation
            FieldMapper<String> uriMapper =
                mappers.get(context.path().fullPathAsText(uriMapperName));
            FieldMapper<String> labelMapper =
                mappers.get(context.path().fullPathAsText(labelMapperName));

            if (uriMapper == null) {
              // No mappers created yet - build new ones for URI and label
              BuilderContext builderContext =
                  new BuilderContext(context.indexSettings(), context.path());
              uriMapper =
                  MapperBuilders.stringField(uriMapperName)
                      .store(true)
                      .index(true)
                      .tokenized(false)
                      .build(builderContext);
              labelMapper =
                  MapperBuilders.stringField(labelMapperName)
                      .store(true)
                      .index(true)
                      .tokenized(true)
                      .build(builderContext);
            }

            addRelatedNodesWithLabels(
                context,
                relations.get(relation),
                uriMapper,
                helper.findLabelsForIRIs(relations.get(relation)),
                labelMapper);
          }
        }
      }

      helper.updateLastCallTime();
    } catch (OntologyHelperException e) {
      throw new ElasticsearchException("Could not initialise ontology helper", e);
    } finally {
      context.path().remove();
      context.path().pathType(origPathType);
    }
  }