Copied to clipboard

Flag this post as spam?

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


  • Alex Perotti 53 posts 94 karma points
    Aug 25, 2015 @ 11:10
    Alex Perotti
    0

    I'm having a bit of trouble creating an examine query

    My index stores two lists of id (comma separated).

    I want to compare these lists with other two lists and get the nodes that have more matches

    Example:

    search1 = "1,20, 50" search2 = "5"

    Index

    node1 { list1 = "55,90", list2 = "1"} node2 { list1 = "50,90", list2 = "1"} node3 { list1 = "1,20,90", list2 = "5"}

    Desidered result

    node3 //3 matches node2 //1 match

    obviously search term "1" shold not match "10"

    Do you have any ideas?

    Thank you

  • Mark Bowser 273 posts 860 karma points c-trib
    Aug 25, 2015 @ 17:20
    Mark Bowser
    1

    This might not be the whole solution, but this is how I've been dealing with searching csvs and not having "1" match "10". Maybe there's a better way, but this is what I've got for the time being. You could probably expand on this and preprocess your node lists into something that is easier to search on. Maybe, on ApplicationStarted, for each node, combine both the list1 and list2 into a single list for searching. That might simplify things.

    On ApplicationStarted, we remove all of the blank space and then convert all of the commas to spaces.

    public class UmbracoEvents : ApplicationEventHandler
    {
        protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            ExamineManager.Instance.IndexProviderCollection["MyCustomIndexer"].GatheringNodeData += OnGatheringNodeData;
        }
    
         protected void OnGatheringNodeData(object sender, IndexingNodeDataEventArgs e)
        {
            // make nodes searchable
            if (e.Fields.ContainsKey("nodes"))
            {
                var nodes = HttpUtility.HtmlDecode(e.Fields["nodes"].ToLower(CultureInfo.InvariantCulture));
                e.Fields["nodes"] = nodes;
                // remove all spaces in each node id list
                // convert commas between items into blank space for the Whitespace Analyzer
                e.Fields["searchNodes"] = e.Fields["nodes"].Replace(" ", "").Replace(',', ' ');
            }
        }
    }
    

    Then we use the WhitespaceAnalyzer in the /config/ExamineSettings.config file.

    analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"
    

    Then, when we search, we do something similar with the search text. We strip out the blank space, and convert the commas into spaces.

    public IEnumerable<IGrouping<string, SearchResult>> SearchNodeLists(IEnumerable<string> csvSearchText)
    {
        if (csvSearchText == null)
        {
            throw new ArgumentNullException("csvSearchText");
        }
    
        var nodeList = csvSearchText.ToList();
    
        var _searcher = ExamineManager.Instance.SearchProviderCollection["MyCustomSearcher"];
        var searchCriteria = _searcher.CreateSearchCriteria();
    
        var luceneString = "";
        foreach (var node in nodeList)
        {
            // remove blank spaces in each nodes
            luceneString += "searchNodes:";
            luceneString += "(+\"" + node.Replace(" ", "") + "\") ";
        }
    
        var query = searchCriteria.RawQuery(luceneString);
        var searchResults = _searcher.Search(query);
    
        return searchResults;
    }
    

    Hope there aren't too many errors in this. I did a lot of copy pasting and editing into this editor, and might have broken something.

  • Alex Perotti 53 posts 94 karma points
    Aug 26, 2015 @ 05:57
    Alex Perotti
    0

    Thank you for you answer.

    I had noticed I've made an error: the values in in the index are actually stored as space separeted, not with comma.

    It seems that the following code is working, but I want to further test it when I will have more data.

    private IEnumerable<SearchResult> RelatedQuery(int blogId, int postId, string nodeTypeAlias, IEnumerable<string> tags, IEnumerable<string> cats, int howMany)
        {
            var searchCriteria = _searcher.CreateSearchCriteria();
            var rawQuery = $"+nodeTypeAlias: {nodeTypeAlias} +blogId:{blogId} -id:{postId}";
            if (tags != null)
            {
                rawQuery += " tags:(";
                foreach (var t in tags)
                {
                    rawQuery += $"{t} ";
                }
                rawQuery += ")";
            }
            if (cats != null)
            {
                rawQuery += " categories:(";
                foreach (var c in cats)
                {
                    rawQuery += $"{c} ";
                }
                rawQuery += ")";
            }
    
            ISearchCriteria query = null;
            query = searchCriteria.RawQuery(rawQuery);
            return _searcher.Search(query).OrderByDescending(x => x.Score).ToList().Take(howMany);
        }
    
Please Sign in or register to post replies

Write your reply to:

Draft