internal static IField GetAttributeField(AttributeIsSetToken token, string attributeName) { if (token is StringAttributeIsSetToken) { return(AttributeFields.String(attributeName)); } if (token is DateTimeAttributeIsSetToken) { return(AttributeFields.DateTime(attributeName)); } if (token is OrgUnitAttributeIsSetToken) { return(AttributeFields.OrgUnit(attributeName)); } if (token is UserStateAttributeIsSetToken) { return(AttributeFields.State(attributeName)); } if (token is IntegerNumberAttributeIsSetToken) { return(AttributeFields.Integer(attributeName)); } if (token is FloatNumberAttributeIsSetToken) { return(AttributeFields.Double(attributeName)); } throw new NotSupportedException($"{token.GetType().Name} is not supported"); }
public string GetSearchRequest(ISearchExpression expression, bool onlyMy = true) { var queryBuilder = QueryBuilderImpl.CreateEmptyQueryBuilder(); var currentUser = _context.GetCurrentPerson(); var currentUserPositions = currentUser.Positions.ToArray(); var allTasksTypes = _taskTypesService.AllTaskTypes .Union(_taskTypesService.AllWorkflowTypes) .ToArray(); var types = GetTypesFromExpression <NextTaskTypeArgumentToken>(expression, allTasksTypes, out _); queryBuilder.Must(ObjectFields.TypeId.BeAnyOf(types.Select(x => x.Id).ToArray())); AddAttributesSearch(expression, queryBuilder); var myToken = expression.Tokens.OfType <NextTaskMySearchToken>().ToList(); if ((!currentUser.IsAdmin && onlyMy) || (!currentUser.IsAdmin && !onlyMy && myToken.Any()) || (currentUser.IsAdmin && myToken.Any())) { var occur = myToken.FirstOrDefault()?.Context?.GetTermOccur() ?? TermOccur.Must; var searchObjects = new List <ISearchTerm>(); var attributeNames = new HashSet <string>(); foreach (var name in allTasksTypes) { attributeNames.UnionWith(name.Attributes.Where(x => x.Type == MAttrType.OrgUnit).Select(x => x.Name)); } foreach (var attribute in attributeNames) { var field = AttributeFields.OrgUnit(attribute); searchObjects.Add(field.BeAnyOf(currentUserPositions)); } queryBuilder.AddAnyOf(searchObjects.ToArray(), occur); } var searchPhraseTokens = expression.Tokens.OfType <NextTaskSearchPhraseToken>(); foreach (var tokenGroup in searchPhraseTokens.GroupBy(x => x.Context.GetTermOccur())) { var keywords = tokenGroup.Select(x => EscapeKeyword(x.Value)).ToList(); foreach (var keyword in keywords) { queryBuilder.Add(ObjectFields.AllText.Be(keyword), tokenGroup.Key); } } var quotedSearchPhraseTokens = expression.Tokens.OfType <NextTaskQuotedSearchPhraseToken>(); foreach (var tokenGroup in quotedSearchPhraseTokens.GroupBy(x => x.Context.GetTermOccur())) { var keywords = tokenGroup.Select(x => EscapeSearchPhrase(x.Value)).ToList(); foreach (var keyword in keywords) { queryBuilder.Add(ObjectFields.AllText.Be(keyword), tokenGroup.Key); } } return(queryBuilder.ToString()); }
protected void AddAttributesSearch(ISearchExpression expression, IQueryBuilder attributesQueryBuilder) { if (attributesQueryBuilder == null) { return; } var attributeIsSetTokens = expression.Tokens.OfType <AttributeIsSetToken>().ToList(); foreach (var group in attributeIsSetTokens.GroupByAttributeAndOccur()) { var token = group.First(); var field = GetAttributeField(token, group.Key.AttributeName); AddIsSetSearch(attributesQueryBuilder, group.Key.AttributeName, field, group.Key.Occur); } var stringAttributeValueTokens = expression.Tokens.OfType <StringAttributeValueToken>().ToList(); foreach (var group in stringAttributeValueTokens.GroupByAttributeAndOccur()) { var attributeName = group.Key.AttributeName; var field = AttributeFields.String(attributeName); var values = group.Select(token => EscapeStringValue(token.Value)); attributesQueryBuilder.AddAnyOf(values.Select(x => field.Be(x)).ToArray(), group.Key.Occur); } var orgUnitValueTokens = expression.Tokens.OfType <OrgUnitAttributeValueToken>().ToList(); foreach (var group in orgUnitValueTokens.GroupByAttributeAndOccur()) { var attributeName = group.Key.AttributeName; var field = AttributeFields.OrgUnit(attributeName); var positions = group .Select(token => token is OrgUnitMeArgumentToken ? _context.GetCurrentPerson() : _context.GetPerson(Convert.ToInt32(token.Id))) .SelectMany(x => x.Positions) .Distinct() .ToArray(); attributesQueryBuilder.Add(field.BeAnyOf(positions), group.Key.Occur); } var stateAttributeValueTokens = expression.Tokens.OfType <UserStateAttributeValueToken>().ToList(); foreach (var group in stateAttributeValueTokens.GroupByAttributeAndOccur()) { var field = AttributeFields.State(group.Key.AttributeName); attributesQueryBuilder.Add(field.BeAnyOf(group.Select(x => Guid.Parse(x.Id)).Distinct().ToArray()), group.Key.Occur); } var dateAttributesNames = expression.Tokens.OfType <DateAttributeNameToken>(); foreach (var dateAttributeNameToken in dateAttributesNames) { var dateFieldName = dateAttributeNameToken.Data; var dateField = AttributeFields.DateTime(dateFieldName); AddDateSearch( token => token.Context[TokenBase.GroupParentKey].Value is DateAttributeNameToken && token.Context[nameof(AttributeNameTokenBase)].Value as string == dateFieldName, datesRange => dateField.BeInRange(datesRange.FromUtc, datesRange.ToUtc), null, expression, attributesQueryBuilder, null); } var numberAttributeTokens = expression.Tokens.OfType <NumberAttributeValueToken>().ToList(); var fromNumAttributesTokens = numberAttributeTokens.Where(x => (bool?)x.Context[RangeToken.IsRangeTopKey].Value != true).ToList(); var toNumAttributesToknes = numberAttributeTokens.Where(x => (bool?)x.Context[RangeToken.IsRangeTopKey].Value == true).ToList(); var numAttributesRanges = new List <NumAttributeRange>(); foreach (var fromRangeToken in fromNumAttributesTokens) { var attributeName = fromRangeToken.Context[nameof(AttributeNameTokenBase)].Value as string; var fromValue = double.Parse(fromRangeToken.Value, CultureInfo.InvariantCulture); var isFloat = fromRangeToken.Context[nameof(FloatNumberAttributeNameToken)].Value != null; if (fromRangeToken.Context[TokenBase.GroupParentKey].Value is NumberAttributeGreaterToken) { numAttributesRanges.Add(new NumAttributeRange(attributeName, isFloat, fromValue, double.PositiveInfinity, fromRangeToken.Context)); continue; } if (fromRangeToken.Context[TokenBase.GroupParentKey].Value is NumberAttributeLessToken) { numAttributesRanges.Add(new NumAttributeRange(attributeName, isFloat, double.NegativeInfinity, fromValue, fromRangeToken.Context)); continue; } var groupParent = fromRangeToken.Context[TokenBase.GroupParentKey].Value; var toRangeToken = toNumAttributesToknes.FirstOrDefault(x => ReferenceEquals(groupParent, x.Context[TokenBase.GroupParentKey].Value)); var toValue = toRangeToken != null ? (double?)double.Parse(toRangeToken.Value, CultureInfo.InvariantCulture) : null; numAttributesRanges.Add(new NumAttributeRange(attributeName, isFloat, fromValue, toValue, fromRangeToken.Context)); } foreach (var range in numAttributesRanges) { var doubleFiled = AttributeFields.Double(range.AttrName); var longField = AttributeFields.Integer(range.AttrName); var fromDoubleValue = range.From; var fromLongValue = double.IsNegativeInfinity(fromDoubleValue) ? long.MinValue : Convert.ToInt64(Math.Floor(fromDoubleValue)); if (range.To == null) { var searchTerm = range.IsFloat ? doubleFiled.Be(fromDoubleValue) : longField.Be(fromLongValue); attributesQueryBuilder.Add(searchTerm, range.Context.GetTermOccur()); } else { var toDoubleValue = (double)range.To; var toLongValue = double.IsPositiveInfinity(toDoubleValue) ? long.MaxValue : Convert.ToInt64(Math.Floor(toDoubleValue)); var searchTerm = range.IsFloat ? doubleFiled.BeInRange(fromDoubleValue, toDoubleValue) : longField.BeInRange(fromLongValue, toLongValue); attributesQueryBuilder.Add(searchTerm, range.Context.GetTermOccur()); } } }