All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yahoo.schema.derived.VsmSummary Maven / Gradle / Ivy

// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.schema.derived;

import com.yahoo.schema.Schema;
import com.yahoo.schema.document.GeoPos;
import com.yahoo.schema.document.SDDocumentType;
import com.yahoo.schema.document.SDField;
import com.yahoo.vespa.documentmodel.DocumentSummary;
import com.yahoo.vespa.documentmodel.SummaryField;
import com.yahoo.vespa.config.search.vsm.VsmsummaryConfig;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Vertical streaming matcher summary specification
 *
 * @author bratseth
 */
public class VsmSummary extends Derived {

    private final Map> summaryMap = new java.util.LinkedHashMap<>(1);

    public VsmSummary(Schema schema) {
        derive(schema);
    }

    @Override
    protected void derive(Schema schema) {
        // Use the default class, as it is the superset
        derive(schema, schema.getSummary("default"));
    }

    private void derive(Schema schema, DocumentSummary documentSummary) {
        if (documentSummary == null) return;
        for (SummaryField summaryField : documentSummary.getSummaryFields().values()) {
            List from = toStringList(summaryField.sourceIterator());

            if (doMapField(schema, summaryField)) {
                SDField sdField = schema.getConcreteField(summaryField.getName());
                if (sdField != null && GeoPos.isAnyPos(sdField)) {
                    summaryMap.put(summaryField, List.of(summaryField.getName()));
                } else {
                    summaryMap.put(summaryField, from);
                }
            }
        }
    }

    /**
     * Don't include field in map if sources are the same as the struct sub fields for the SDField.
     * But do map if not all do summarying.
     * Don't map if not struct either.
     * @param summaryField a {@link SummaryField}
     */
    private boolean doMapField(Schema schema, SummaryField summaryField) {
        SDField sdField = schema.getConcreteField(summaryField.getName());
        SDDocumentType document = schema.getDocument();
        if (sdField==null || ((document != null) && (document.getField(summaryField.getName()) == sdField))) {
            return true;
        }
        if (summaryField.getVsmCommand().equals(SummaryField.VsmCommand.FLATTENJUNIPER)) {
            return true;
        }
        if (!sdField.usesStructOrMap()) {
            return !(sdField.getName().equals(summaryField.getName()));
        }
        if (summaryField.getSourceCount()==sdField.getStructFields().size()) {
            for (SummaryField.Source source : summaryField.getSources()) {
                if (!sdField.getStructFields().contains(new SDField(schema.getDocument(), source.getName(), sdField.getDataType()))) { // equals() uses just name
                    return true;
                }
                if (sdField.getStructField(source.getName())!=null && !sdField.getStructField(source.getName()).doesSummarying()) {
                    return true;
                }
            }
            // The sources in the summary field are the same as the sub-fields in the SD field.
            // All sub fields do summarying.
            // Don't map.
            return false;
        }
        return true;
    }

    private List toStringList(Iterator i) {
        List ret = new ArrayList<>();
        while (i.hasNext()) {
            ret.add(i.next().getName());
        }
        return ret;
    }

    @Override public String getDerivedName() {
        return "vsmsummary";
    }

    public void getConfig(VsmsummaryConfig.Builder vB) {
        // Replace
        vB.fieldmap(
                summaryMap.entrySet().stream().map(entry -> new VsmsummaryConfig.Fieldmap.Builder()
                        .summary(entry.getKey().getName())
                        .document(entry.getValue().stream().map(field -> new VsmsummaryConfig.Fieldmap.Document.Builder().field(field)).toList())
                        .command(VsmsummaryConfig.Fieldmap.Command.Enum.valueOf(entry.getKey().getVsmCommand().toString()))
                ).toList()
        );
    }

    public void export(String toDirectory) throws IOException {
        var builder = new VsmsummaryConfig.Builder();
        getConfig(builder);
        export(toDirectory, builder.build());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy