in src/StructuredLogger/Search/NodeQueryMatcher.cs [434:580]
public SearchResult IsMatch(BaseNode node)
{
SearchResult result = null;
if (node == null)
{
return null;
}
if (NodeIndex > -1)
{
if (node is TimedNode timedNode && timedNode.Index == NodeIndex)
{
result = new SearchResult(node);
var prefix = "Node id: ";
result.AddMatch(prefix + NodeIndex.ToString(), NodeIndex.ToString());
return result;
}
}
var searchFields = PopulateSearchFields(node);
if (TypeKeyword != null)
{
// zeroth field is always the type
if (string.Equals(TypeKeyword, searchFields.array[0], StringComparison.OrdinalIgnoreCase) ||
// special case for types derived from Task, $task should still work
(TypeKeyword == "task" && searchFields.count > 1 && searchFields.array[1] == "Task"))
{
// this node is of the type that we need, search other fields
if (result == null)
{
result = new SearchResult(node, IncludeDuration, IncludeStart, IncludeEnd);
}
result.AddMatchByNodeType();
}
else
{
return null;
}
}
bool nameMatched = false;
bool valueMatched = false;
for (int i = 0; i < Words.Count; i++)
{
bool anyFieldMatched = false;
var term = Words[i];
var word = term.Word;
for (int j = 0; j < searchFields.count; j++)
{
var field = searchFields.array[j];
//if (!stringCache.Contains(field))
//{
//}
if (!term.IsMatch(field, MatchesInStrings[i]))
{
continue;
}
if (result == null)
{
result = new SearchResult(node, IncludeDuration, IncludeStart, IncludeEnd);
}
// if matched on the type of the node (always field 0), special case it
if (j == 0)
{
result.AddMatchByNodeType();
}
else
{
string fullText = field;
var nameValueNode = node as NameValueNode;
// NameValueNode is a special case: have to check in which field to search
if (nameValueNode != null && (nameToSearch != default || valueToSearch != default))
{
if (j == 1 && term == nameToSearch)
{
result.AddMatch(fullText, word, addAtBeginning: true);
nameMatched = true;
anyFieldMatched = true;
break;
}
if (j == 2 && term == valueToSearch)
{
result.AddMatch(fullText, word);
valueMatched = true;
anyFieldMatched = true;
break;
}
}
else
{
result.AddMatch(fullText, word);
anyFieldMatched = true;
break;
}
}
}
if (!anyFieldMatched)
{
return null;
}
}
if (result == null)
{
return null;
}
if (nameToSearch != default && valueToSearch != default && (!nameMatched || !valueMatched))
{
return null;
}
bool showResult = IncludeMatchers.Count == 0;
foreach (NodeQueryMatcher matcher in IncludeMatchers)
{
if (!showResult)
{
showResult = IsUnder(matcher, result);
}
}
if (!showResult)
{
return null;
}
foreach (NodeQueryMatcher matcher in ExcludeMatchers)
{
if (IsUnder(matcher, result))
{
return null;
}
}
return result;
}