È necessario abbinare i tag del database usando un'espressione booleana

1

Ho una tabella, chiamiamola Widget, una tabella Tag con circa 30 tag, una tabella WidgetTags che unisce ogni widget con qualsiasi numero di tag e una tabella chiamata LandingPages, le pagine di destinazione sono per scopi SEO, offrono versioni pre-filtrate della tabella dei widget che corrispondono alle ricerche popolari. In questo modo, quando qualcuno cerca "Widget per veicoli in vendita in Florida", in cui la logica dei tag corrispondenti sarebbe simile a questa:

For-Sale && Florida && (Car || Motorcycle || Truck)

Ci possono essere altre forme di logica booleana per le varie pagine di destinazione.

Quello che voglio fare è che quando un utente aggiunge un widget alla mia app e seleziona una manciata di tag, l'app sa quali pagine di destinazione assegnare a quel widget, in base alla logica del tag di ciascuna pagina di destinazione. Sto discutendo la memorizzazione di un'espressione booleana reale come un varchar nella pagina di destinazione, quindi l'analisi di ciascuna quando viene aggiunto un widget. O una sorta di sistema di tabelle, ma ho pensato che qualcuno abbia già affrontato questo problema. Se aiuta, sto usando C #, con un back-end di SQL Server.

    
posta Neil N 20.03.2017 - 21:19
fonte

1 risposta

0

Ho deciso di utilizzare un campo varchar nella tabella LandingPages per memorizzare un'espressione booleana. Quindi, quando viene aggiunto un widget, viene caricato l'elenco di LandingPages, quindi l'espressione booleana viene eseguita sui tag per quel widget, quelli che restituiscono true ottengono quel widget associato.

Va in questo modo:

var evaluator = new ExpressionEvaluator();
evaluator.Tags = widget.Tags;  // List<string>

foreach(var page in LandginPages)
{
    if(evaluator.Evaluate(page.filterExpression))
    {
        // Create widget <-> LandingPage association here
    }
}

La classe del valutatore di espressioni che ho creato:

public class ExpressionEvaluator
{
    public List<string> Tags = new List<string>();

    public bool Evaluate(string exp)
    {
        // Split on first space
        var tokens = exp.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);

        // If just one or none, eval the tag
        if (tokens.Length < 2)
        {
            return Tags.Contains(exp);
        }

        // Pull out the left, op, right
        var left = tokens[0];
        var op = tokens[1];
        var right = tokens[2];

        switch (op)
        {
            case "&&":
                return AND(left, right);
                break;
            case "||":
                return OR(left, right);
                break;
        }

        return false;
    }

    private bool AND(string left, string right)
    {
        // Short circuit on the left
        if (!Tags.Contains(left))
        {
            return false;
        }

        return Evaluate(right);
    }

    private bool OR(string left, string right)
    {
        // Short circuit on the left
        if(Tags.Contains(left))
        {
            return true;
        }

        return Evaluate(right);
    }
}

Per vedere tutti i test che ho scritto per creare questo corso, controlla il repository su GitHub: link

    
risposta data 22.03.2017 - 14:05
fonte

Leggi altre domande sui tag