Example #1
0
 @Override
 public void postDeleteUnderLock(Engine.Delete delete) {
   // remove the query under a lock
   if (PercolatorService.TYPE_NAME.equals(delete.type())) {
     removePercolateQuery(delete.id());
   }
 }
  // never expose this to the outside world, we need to reparse the doc mapper so we get fresh
  // instances of field mappers to properly remove existing doc mapper
  private DocumentMapper merge(DocumentMapper mapper) {
    synchronized (typeMutex) {
      if (mapper.type().length() == 0) {
        throw new InvalidTypeNameException("mapping type name is empty");
      }
      if (mapper.type().charAt(0) == '_' && !PercolatorService.TYPE_NAME.equals(mapper.type())) {
        throw new InvalidTypeNameException(
            "mapping type name [" + mapper.type() + "] can't start with '_'");
      }
      if (mapper.type().contains("#")) {
        throw new InvalidTypeNameException(
            "mapping type name [" + mapper.type() + "] should not include '#' in it");
      }
      if (mapper.type().contains(",")) {
        throw new InvalidTypeNameException(
            "mapping type name [" + mapper.type() + "] should not include ',' in it");
      }
      if (mapper.type().contains(".")) {
        logger.warn(
            "Type [{}] contains a '.', it is recommended not to include it within a type name",
            mapper.type());
      }
      // we can add new field/object mappers while the old ones are there
      // since we get new instances of those, and when we remove, we remove
      // by instance equality
      DocumentMapper oldMapper = mappers.get(mapper.type());

      if (oldMapper != null) {
        DocumentMapper.MergeResult result = oldMapper.merge(mapper, mergeFlags().simulate(false));
        if (result.hasConflicts()) {
          // TODO: What should we do???
          if (logger.isDebugEnabled()) {
            logger.debug(
                "merging mapping for type [{}] resulted in conflicts: [{}]",
                mapper.type(),
                Arrays.toString(result.conflicts()));
          }
        }
        return oldMapper;
      } else {
        FieldMapperListener.Aggregator fieldMappersAgg = new FieldMapperListener.Aggregator();
        mapper.traverse(fieldMappersAgg);
        addFieldMappers(
            fieldMappersAgg.mappers.toArray(new FieldMapper[fieldMappersAgg.mappers.size()]));
        mapper.addFieldMapperListener(fieldMapperListener, false);

        ObjectMapperListener.Aggregator objectMappersAgg = new ObjectMapperListener.Aggregator();
        mapper.traverse(objectMappersAgg);
        addObjectMappers(
            objectMappersAgg.mappers.toArray(new ObjectMapper[objectMappersAgg.mappers.size()]));
        mapper.addObjectMapperListener(objectMapperListener, false);

        mappers = newMapBuilder(mappers).put(mapper.type(), mapper).map();
        for (DocumentTypeListener typeListener : typeListeners) {
          typeListener.created(mapper.type());
        }
        return mapper;
      }
    }
  }
Example #3
0
 @Override
 public void postIndexUnderLock(Engine.Index index) {
   // add the query under a doc lock
   if (PercolatorService.TYPE_NAME.equals(index.type())) {
     addPercolateQuery(index.id(), index.source());
   }
 }
Example #4
0
 @Override
 public void postCreateUnderLock(Engine.Create create) {
   // add the query under a doc lock
   if (PercolatorService.TYPE_NAME.equals(create.type())) {
     addPercolateQuery(create.id(), create.source());
   }
 }
Example #5
0
 @Override
 public void afterRemove(DocumentMapper mapper) {
   if (PercolatorService.TYPE_NAME.equals(mapper.type())) {
     disableRealTimePercolator();
     clear();
   }
 }
Example #6
0
 @Override
 public Engine.Index preIndex(Engine.Index index) {
   // validate the query here, before we index
   if (PercolatorService.TYPE_NAME.equals(index.type())) {
     parsePercolatorDocument(index.id(), index.source());
   }
   return index;
 }
Example #7
0
 @Override
 public Engine.Create preCreate(Engine.Create create) {
   // validate the query here, before we index
   if (PercolatorService.TYPE_NAME.equals(create.type())) {
     parsePercolatorDocument(create.id(), create.source());
   }
   return create;
 }
 public DocumentMapper parse(String mappingType, String mappingSource, boolean applyDefault)
     throws MapperParsingException {
   String defaultMappingSource;
   if (PercolatorService.TYPE_NAME.equals(mappingType)) {
     defaultMappingSource = this.defaultPercolatorMappingSource;
   } else {
     defaultMappingSource = this.defaultMappingSource;
   }
   return documentParser.parse(
       mappingType, mappingSource, applyDefault ? defaultMappingSource : null);
 }
Example #9
0
 @Override
 public void beforeCreate(DocumentMapper mapper) {
   if (PercolatorService.TYPE_NAME.equals(mapper.type())) {
     enableRealTimePercolator();
   }
 }
Example #10
0
  /**
   * A filter for search. If a filter is required, will return it, otherwise, will return
   * <tt>null</tt>.
   */
  @Nullable
  public Filter searchFilter(String... types) {
    boolean filterPercolateType = hasMapping(PercolatorService.TYPE_NAME);
    if (types != null && filterPercolateType) {
      for (String type : types) {
        if (PercolatorService.TYPE_NAME.equals(type)) {
          filterPercolateType = false;
          break;
        }
      }
    }
    Filter excludePercolatorType = null;
    if (filterPercolateType) {
      excludePercolatorType =
          new NotFilter(documentMapper(PercolatorService.TYPE_NAME).typeFilter());
    }

    if (types == null || types.length == 0) {
      if (hasNested && filterPercolateType) {
        return new AndFilter(ImmutableList.of(excludePercolatorType, NonNestedDocsFilter.INSTANCE));
      } else if (hasNested) {
        return NonNestedDocsFilter.INSTANCE;
      } else if (filterPercolateType) {
        return excludePercolatorType;
      } else {
        return null;
      }
    }
    // if we filter by types, we don't need to filter by non nested docs
    // since they have different types (starting with __)
    if (types.length == 1) {
      DocumentMapper docMapper = documentMapper(types[0]);
      if (docMapper == null) {
        return new TermFilter(new Term(types[0]));
      }
      return docMapper.typeFilter();
    }
    // see if we can use terms filter
    boolean useTermsFilter = true;
    for (String type : types) {
      DocumentMapper docMapper = documentMapper(type);
      if (docMapper == null) {
        useTermsFilter = false;
        break;
      }
      if (!docMapper.typeMapper().fieldType().indexed()) {
        useTermsFilter = false;
        break;
      }
    }

    if (useTermsFilter) {
      BytesRef[] typesBytes = new BytesRef[types.length];
      for (int i = 0; i < typesBytes.length; i++) {
        typesBytes[i] = new BytesRef(types[i]);
      }
      TermsFilter termsFilter = new TermsFilter(TypeFieldMapper.NAME, typesBytes);
      if (filterPercolateType) {
        return new AndFilter(ImmutableList.of(excludePercolatorType, termsFilter));
      } else {
        return termsFilter;
      }
    } else {
      // Current bool filter requires that at least one should clause matches, even with a must
      // clause.
      XBooleanFilter bool = new XBooleanFilter();
      for (String type : types) {
        DocumentMapper docMapper = documentMapper(type);
        if (docMapper == null) {
          bool.add(
              new FilterClause(
                  new TermFilter(new Term(TypeFieldMapper.NAME, type)),
                  BooleanClause.Occur.SHOULD));
        } else {
          bool.add(new FilterClause(docMapper.typeFilter(), BooleanClause.Occur.SHOULD));
        }
      }
      if (filterPercolateType) {
        bool.add(excludePercolatorType, BooleanClause.Occur.MUST);
      }

      return bool;
    }
  }
  /**
   * A filter for search. If a filter is required, will return it, otherwise, will return
   * <tt>null</tt>.
   */
  @Nullable
  public Query searchFilter(String... types) {
    boolean filterPercolateType = hasMapping(PercolatorService.TYPE_NAME);
    if (types != null && filterPercolateType) {
      for (String type : types) {
        if (PercolatorService.TYPE_NAME.equals(type)) {
          filterPercolateType = false;
          break;
        }
      }
    }
    Query percolatorType = null;
    if (filterPercolateType) {
      percolatorType = documentMapper(PercolatorService.TYPE_NAME).typeFilter();
    }

    if (types == null || types.length == 0) {
      if (hasNested && filterPercolateType) {
        BooleanQuery bq = new BooleanQuery();
        bq.add(percolatorType, Occur.MUST_NOT);
        bq.add(Queries.newNonNestedFilter(), Occur.MUST);
        return new ConstantScoreQuery(bq);
      } else if (hasNested) {
        return Queries.newNonNestedFilter();
      } else if (filterPercolateType) {
        return new ConstantScoreQuery(Queries.not(percolatorType));
      } else {
        return null;
      }
    }
    // if we filter by types, we don't need to filter by non nested docs
    // since they have different types (starting with __)
    if (types.length == 1) {
      DocumentMapper docMapper = documentMapper(types[0]);
      Query filter =
          docMapper != null
              ? docMapper.typeFilter()
              : new TermQuery(new Term(TypeFieldMapper.NAME, types[0]));
      if (filterPercolateType) {
        BooleanQuery bq = new BooleanQuery();
        bq.add(percolatorType, Occur.MUST_NOT);
        bq.add(filter, Occur.MUST);
        return new ConstantScoreQuery(bq);
      } else {
        return filter;
      }
    }
    // see if we can use terms filter
    boolean useTermsFilter = true;
    for (String type : types) {
      DocumentMapper docMapper = documentMapper(type);
      if (docMapper == null) {
        useTermsFilter = false;
        break;
      }
      if (docMapper.typeMapper().fieldType().indexOptions() == IndexOptions.NONE) {
        useTermsFilter = false;
        break;
      }
    }

    // We only use terms filter is there is a type filter, this means we don't need to check for
    // hasNested here
    if (useTermsFilter) {
      BytesRef[] typesBytes = new BytesRef[types.length];
      for (int i = 0; i < typesBytes.length; i++) {
        typesBytes[i] = new BytesRef(types[i]);
      }
      TermsQuery termsFilter = new TermsQuery(TypeFieldMapper.NAME, typesBytes);
      if (filterPercolateType) {
        BooleanQuery bq = new BooleanQuery();
        bq.add(percolatorType, Occur.MUST_NOT);
        bq.add(termsFilter, Occur.MUST);
        return new ConstantScoreQuery(bq);
      } else {
        return termsFilter;
      }
    } else {
      // Current bool filter requires that at least one should clause matches, even with a must
      // clause.
      BooleanQuery bool = new BooleanQuery();
      for (String type : types) {
        DocumentMapper docMapper = documentMapper(type);
        if (docMapper == null) {
          bool.add(new TermQuery(new Term(TypeFieldMapper.NAME, type)), BooleanClause.Occur.SHOULD);
        } else {
          bool.add(docMapper.typeFilter(), BooleanClause.Occur.SHOULD);
        }
      }
      if (filterPercolateType) {
        bool.add(percolatorType, BooleanClause.Occur.MUST_NOT);
      }
      if (hasNested) {
        bool.add(Queries.newNonNestedFilter(), BooleanClause.Occur.MUST);
      }

      return new ConstantScoreQuery(bool);
    }
  }
 private boolean typeNameStartsWithIllegalDot(DocumentMapper mapper) {
   return mapper.type().startsWith(".") && !PercolatorService.TYPE_NAME.equals(mapper.type());
 }