Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Frederik T 241 posts 372 karma points
    18 days ago
    Frederik T
    0

    Umbraco 13 - Examine searches all sites in a multisite setup

    At my workplace we have inherited an Umbraco website that I need to do some maintenance on. It consists of five websites, each in different languages. They all use the same templates, partial view etc.

    The problem is that it has a global search functionality that utilizes Examine, which searches across all sites, and not just the site you are on currently.

    I have tried, and tried, and tried again to do something about this with the limited knowledge of Examine I have but no solution in sight. One would think that this is a common problem since multi-sites is a cornerstone feature of Umbraco, but after hours of searching I have found nothing concrete or its for very old versions of Umbraco.

    Here is the code that does the searching with my feeble attempt at solving this. This is but one of many, many different methods I have tried. The point is that I supply the method with the ID of the sites home node, and then try to filter it out with the "__path" examine field which contains the home node id:

    public SearchResults SearchContent(string query, string culture = "da", int page = 1, int pageSize = 20, int rootNodeId = -1)
    {
        _variationContextAccessor.VariationContext = new VariationContext(culture);
        string[] SEARCHABLE_FIELDS = new[] { string.Format("nodeName_{0}", culture), string.Format("heading_{0}", culture), string.Format("sections_{0}", culture), string.Format("cSectionPageSections_{0}", culture) };
    
        IEnumerable<string> ids = Array.Empty<string>();
    
        if (!_examineManager.TryGetIndex(Constants.UmbracoIndexes.ExternalIndexName, out IIndex index))
        {
            throw new InvalidOperationException($"No index found by name {Constants.UmbracoIndexes.ExternalIndexName}");
        }
    
        if (string.IsNullOrEmpty(query) || query.Length < 3)
            throw new ArgumentNullException("Query is empty or less than 3");
    
        ISearcher searcher = index.Searcher;
        var criteria = searcher.CreateQuery(IndexTypes.Content, BooleanOperation.And);
        var examineQuery = criteria.GroupedOr(new string[] { "__NodeTypeAlias" }, SEARCHABLE_NODES);
        var terms = query.Split(' ').Where(x => !string.IsNullOrEmpty(x)).Select(x => x.ToSafeAlias(_shortStringHelper).MultipleCharacterWildcard()).ToArray();
        examineQuery.And().GroupedOr(SEARCHABLE_FIELDS, terms);
    
        // filter results by their home node id
        if (rootNodeId != -1)
        {
            examineQuery.And().Field("__Path", $"-1,{rootNodeId},-1");
        }
    
        // Execute the search
        int pageIndex = page - 1;
        QueryOptions queryOptions = new(pageIndex * pageSize, pageSize);
        ISearchResults searchResult = examineQuery.Execute(queryOptions);
        IEnumerable<ISearchResult> pagedResults = searchResult.Skip(pageIndex * pageSize).ToList();
        ids = pagedResults.Select(x => x.Id);
        int totalResults = Convert.ToInt32(searchResult.TotalItemCount);
    
        SearchResults results = new()
        {
            Results = TransformResults(ids),
            CurrentPage = page,
            TotalResults = totalResults,
            TotalPages = (totalResults + pageSize - 1) / pageSize
        };
    
        return results;
    }
    

    I have also tried this:

    if (rootNodeId > 0)
    {
        examineQuery.And().Field("__Path", rootNodeId.ToString());
    }
    

    And this:

    if (rootNodeId > 0)
    {
        string rootNodePath = $",{rootNodeId},";
        examineQuery.And().Field("__Path", rootNodePath.MultipleCharacterWildcard());
    }
    

    And a few others.

    This seems it MIGHT be working, but to be honest I dont exactly understand "why" at this point, and my gut feeling tells me there is a better approach:

    if (rootNodeId > 0)
    {
        examineQuery.And().Field("__Path", ("-1," + rootNodeId.ToString() + ",").MultipleCharacterWildcard());
    }
    
  • Frederik T 241 posts 372 karma points
    1 hour ago
    Frederik T
    0

    Over two weeks, is there seriously not a single one out there who has used this in a multi site setup?

Please Sign in or register to post replies

Write your reply to:

Draft