예제 #1
0
        public virtual SearchResult <SearchableBase> Search(SearchTextQuery query)
        {
            var searchRequest = GetSearchDescriptor()
                                .Query(q =>
                                       q.Bool(b => b
                                              .Should(GetQueryContainers(query.Text))
                                              .MinimumShouldMatch(MinimumShouldMatch.Fixed(MinimumShouldMatches))))
                                .PostFilter(pf => pf.Bool(b => b.Must(GetSearchPostFilters(query))));

            ApplyAggregations(searchRequest, query);

            _searchSorting.Apply(searchRequest, query);

            _searchPagingHelper.Apply(searchRequest, query);

            if (query.ApplyHighlights)
            {
                ApplyHighlight(searchRequest);
            }

            var queryResult  = _elasticSearchRepository.SearchByIndex(searchRequest);
            var searchResult = ParseResults(queryResult);

            return(searchResult);
        }
예제 #2
0
 protected override QueryContainer QueryFluent(QueryContainerDescriptor <Project> q) => q
 .Terms(c => c
        .Name("named_query")
        .Boost(1.1)
        .Field(p => p.Description)
        .DisableCoord()
        .MinimumShouldMatch(MinimumShouldMatch.Fixed(2))
        .Terms("term1")
        );
예제 #3
0
        public virtual SearchResult <T> Search(MemberSearchQuery query)
        {
            var shouldDescriptor = new QueryContainerDescriptor <SearchableMember>()
                                   .Bool(b => b.Should(_memberSearchDescriptorBuilder.GetMemberDescriptors(query.Text)));

            QueryContainer allDescriptors = null;

            if (!query.GroupId.HasValue)
            {
                allDescriptors = new QueryContainerDescriptor <T>()
                                 .Bool(b => b
                                       .Must(shouldDescriptor));
            }
            else
            {
                if (query.MembersOfGroup)
                {
                    allDescriptors = new QueryContainerDescriptor <T>()
                                     .Bool(b => b
                                           .Must(shouldDescriptor, _memberSearchDescriptorBuilder.GetMemberInGroupDescriptor(query.GroupId)));
                }
            }

            var searchRequest = GetSearchDescriptor()
                                .Query(q =>
                                       q.Bool(b => b
                                              .Should(allDescriptors)
                                              .MinimumShouldMatch(MinimumShouldMatch.Fixed(MinimumShouldMatches))));

            if (query.GroupId.HasValue && !query.MembersOfGroup)
            {
                searchRequest = GetSearchDescriptor()
                                .Query(q =>
                                       q.Bool(b => b
                                              .Should(_memberSearchDescriptorBuilder.GetMemberDescriptors(query.Text))
                                              .MinimumShouldMatch(MinimumShouldMatch.Fixed(MinimumShouldMatches))))
                                .PostFilter(pf => pf
                                            .Bool(b => b
                                                  .MustNot(_memberSearchDescriptorBuilder.GetMemberInGroupDescriptor(query.GroupId))));
            }

            SortByMemberGroupRights(searchRequest, query);

            _searchPagingHelper.Apply(searchRequest, query);

            var queryResult  = _elasticSearchRepository.SearchByIndex(searchRequest);
            var searchResult = ParseResults(queryResult);

            return(searchResult);
        }
예제 #4
0
        public void match2()
        {
            // 需要全部满足
            var r1 = Proxy.SearchDocAsync <IndexDataInfo>(IndexName,
                                                          query: (q) =>
                                                          q.Match(mq => mq.Field(info => info.title)
                                                                  .Query("华为手机")
                                                                  // .MinimumShouldMatch(MinimumShouldMatch.Fixed(3))
                                                                  .Operator(Operator.And)
                                                                  )).Result;

            // 至少满足N项
            var r2 = Proxy.SearchDocAsync <IndexDataInfo>(IndexName,
                                                          query: (q) =>
                                                          q.Match(mq => mq.Field(info => info.title)
                                                                  .Query("华为手机")
                                                                  .MinimumShouldMatch(MinimumShouldMatch.Fixed(3))
                                                                  .Boost(0)
                                                                  )).Result;
        }
예제 #5
0
        public async Task <SearchResults <PublicScheme> > SearchSchemesAsync(SearchOptions options, CancellationToken cancellationToken = default)
        {
            var shoulds = new List <QueryBase>();

            if (!string.IsNullOrWhiteSpace(options.Query))
            {
                shoulds.Add(new SimpleQueryStringQuery
                {
                    Query  = options.Query,
                    Fields = new[] {
                        nameof(PublicScheme.Name).ToUpper() + "^3",
                        nameof(PublicScheme.Description).ToUpper() + "^2",
                        nameof(PublicScheme.PublisherName).ToUpper()
                    },
                    Boost = 1.5
                });
            }
            var filters = new List <QueryBase>();

            if (options.Side != SchemeSide.any)
            {
                var rangeQuery = new NumericRangeQuery
                {
                    Field = $"{nameof(PublicScheme.ColorScheme)}.{nameof(ColorScheme.backgroundLightnessLimit)}".ToUpper(),
                };
                switch (options.Side)
                {
                case SchemeSide.dark:
                    rangeQuery.LessThan = 30;
                    break;

                case SchemeSide.light:
                    rangeQuery.GreaterThan = 70;
                    break;
                }
                filters.Add(rangeQuery);
            }

            if (options.Bg != HueFilter.any)
            {
                var bgSatField = $"{nameof(PublicScheme.ColorScheme)}.{nameof(ColorScheme.backgroundGraySaturation)}".ToUpper();

                if (options.Bg == HueFilter.gray)
                {
                    var grayFilter = new NumericRangeQuery
                    {
                        Field    = bgSatField,
                        LessThan = 10
                    };
                    filters.Add(grayFilter);
                    var noBlueFilter = new NumericRangeQuery
                    {
                        Field    = $"{nameof(PublicScheme.ColorScheme)}.{nameof(ColorScheme.blueFilter)}".ToUpper(),
                        LessThan = 5
                    };
                    filters.Add(noBlueFilter);
                }
                else
                {
                    var notGrayFilter = new NumericRangeQuery
                    {
                        Field       = bgSatField,
                        GreaterThan = 1
                    };
                    filters.Add(notGrayFilter);

                    if (options.Bg == HueFilter.red)
                    {
                        var field     = $"{nameof(PublicScheme.ColorScheme)}.{nameof(ColorScheme.backgroundGrayHue)}".ToUpper();
                        var redFilter = new BoolQuery
                        {
                            MinimumShouldMatch = 1,
                            Should             = new[] {
                                new QueryContainer(new NumericRangeQuery {
                                    Field = field,
                                    GreaterThanOrEqualTo = 330
                                }),
                                new QueryContainer(new NumericRangeQuery {
                                    Field             = field,
                                    LessThanOrEqualTo = 30
                                })
                            }
                        };
                        filters.Add(redFilter);
                    }
                    else
                    {
                        var rangeQuery = new NumericRangeQuery
                        {
                            Field = $"{nameof(PublicScheme.ColorScheme)}.{nameof(ColorScheme.backgroundGrayHue)}".ToUpper(),
                        };
                        switch (options.Bg)
                        {
                        case HueFilter.yellow:
                            rangeQuery.GreaterThanOrEqualTo = 30;
                            rangeQuery.LessThanOrEqualTo    = 90;
                            break;

                        case HueFilter.green:
                            rangeQuery.GreaterThanOrEqualTo = 90;
                            rangeQuery.LessThanOrEqualTo    = 150;
                            break;

                        case HueFilter.cyan:
                            rangeQuery.GreaterThanOrEqualTo = 150;
                            rangeQuery.LessThanOrEqualTo    = 210;
                            break;

                        case HueFilter.blue:
                            rangeQuery.GreaterThanOrEqualTo = 210;
                            rangeQuery.LessThanOrEqualTo    = 270;
                            break;

                        case HueFilter.purple:
                            rangeQuery.GreaterThanOrEqualTo = 270;
                            rangeQuery.LessThanOrEqualTo    = 330;
                            break;

                        default:
                            break;
                        }
                        filters.Add(rangeQuery);
                    }
                }
            }

            if (!string.IsNullOrWhiteSpace(options.CurrentUserId))
            {
                switch (options.List)
                {
                case SchemeList.my:
                    filters.Add(new MatchPhraseQuery
                    {
                        Field = nameof(PublicScheme.PublisherId).ToUpper(),
                        Query = options.CurrentUserId
                    });
                    break;

                case SchemeList.fav:
                    filters.Add(new MatchPhraseQuery
                    {
                        Field = nameof(PublicScheme.FavoritedBy).ToUpper(),
                        Query = options.CurrentUserId
                    });
                    break;

                case SchemeList.liked:
                    filters.Add(new MatchPhraseQuery
                    {
                        Field = nameof(PublicScheme.LikedBy).ToUpper(),
                        Query = options.CurrentUserId
                    });
                    break;

                default:
                    break;
                }
            }
            else if (new[] { SchemeList.my, SchemeList.fav, SchemeList.liked }.Contains(options.List))
            {
                filters.Add(new MatchNoneQuery());
            }
            if (new[] { SchemeList.com, SchemeList.ml }.Contains(options.List))
            {
                filters.Add(new TermQuery
                {
                    Field = nameof(PublicScheme.PublisherCommunity).ToUpper(),
                    Value = options.List == SchemeList.com
                });
            }
            var results = await this.elasticClient.SearchAsync <PublicScheme>(s =>
            {
                var query = s.Query(q => filters.Count > 0 || shoulds.Count > 0
                    ? q.Bool(cs =>
                {
                    var boolQuery = cs;
                    if (filters.Count > 0)
                    {
                        boolQuery = boolQuery
                                    .Filter(filters.Select(f => new QueryContainer(f)).ToArray());
                    }
                    if (shoulds.Count > 0)
                    {
                        boolQuery = boolQuery
                                    .Should(shoulds.Select(f => new QueryContainer(f)).ToArray())
                                    .MinimumShouldMatch(MinimumShouldMatch.Fixed(1));
                    }
                    return(boolQuery);
                })
                    : q.MatchAll());
                if (!string.IsNullOrWhiteSpace(options.Cursor))
                {
                    query = query.SearchAfter(Encoding.UTF8
                                              .GetString(Convert
                                                         .FromBase64String(options.Cursor))
                                              .Split(',')
                                              .ToArray());
                }
                return(query
                       .Sort(ss => ss
                             .Descending(SortSpecialField.Score)
                             .Field(f => f
                                    .Field(nameof(PublicScheme.Likes).ToUpper())
                                    .Order(SortOrder.Descending)
                                    .UnmappedType(FieldType.Integer)
                                    .MissingLast())
                             .Field(f => f
                                    .Field(nameof(PublicScheme.Favorites).ToUpper())
                                    .Order(SortOrder.Descending)
                                    .UnmappedType(FieldType.Integer)
                                    .MissingLast())
                             .Ascending(SortSpecialField.DocumentIndexOrder))
                       .Size(options.PageSize));
            }, cancellationToken);

            if (results.IsValid)
            {
                return(new SearchResults <PublicScheme>
                {
                    Done = results.Documents.Count() < options.PageSize,
                    Results = results.Documents,
                    Cursor = Convert
                             .ToBase64String(Encoding.UTF8
                                             .GetBytes(string
                                                       .Join(',', results.Hits.LastOrDefault()?.Sorts ?? new object[] { })))
                });
            }
            throw new ApplicationException("Failed to query color schemes.",
                                           results.OriginalException ?? new Exception(results.ServerError.Error.Reason));
        }
예제 #6
0
        private static void QueryMatchingBlogs(IElasticClient elastic)
        {
            var matchResult = elastic.Search <BlogPost>(s =>
                                                        s.Query(q => q.Match(m =>
                                                                             m.Field(f => f.Title)
                                                                             .Query("test post 123")
                                                                             .Operator(Operator.Or).
                                                                             MinimumShouldMatch(MinimumShouldMatch.Fixed(1)))));

            Console.WriteLine(matchResult.ApiCall.Success);
            Console.WriteLine(matchResult.Hits.Count());

            foreach (var hit in matchResult.Hits)
            {
                Console.WriteLine(hit.Source);
            }
        }
예제 #7
0
        public SearchResult Search(DateTime arrival, int nights, decimal?maxPrice = null, IEnumerable <TermFilterDTO> terms = null, string text = null, int offset = 0)
        {
            var sw = new Stopwatch();

            sw.Start();
            slimLock.EnterReadLock();

            var departure = arrival.AddDays(nights);


            var searchResponse = client.Search <RoomDocument>(descriptor =>
                                                              descriptor
                                                              .Index(indexName)
                                                              .From(offset)
                                                              .Size(10)
                                                              .Aggregations(aggregations => {
                // We don't need aggregations when we're loading more pages of the
                // search we did earliear, since we already got that information
                if (offset > 0)
                {
                    return(aggregations);
                }

                return(aggregations
                       .Terms("hotelName", aggr => aggr.Field("hotelName"))
                       .Terms("services", aggr => aggr.Field("services"))
                       .Terms("bedTypes", aggr => aggr.Field("bedTypes"))
                       //.Terms("IsDiscounted", aggr => aggr.Field("isDiscounted"))
                       .Terms("totalPeople", aggr => aggr.Field("totalPeople"))
                       //.Range("priceRange", aggr => aggr.Field("price").Ranges(range => range.To(70), range => range.From(70).To(90), range => range.From(90).To(110), range => range.From(110)))
                       );
            }
                                                                            )
                                                              .Query(query =>
                                                                     query.FunctionScore(score =>
                                                                                         score.BoostMode(FunctionBoostMode.Sum).Functions(function => function.FieldValueFactor(value => value.Field("rating")))
                                                                                         .Query(scoreQuery => scoreQuery.Bool(boolquery =>
            {
                var must               = new List <Func <QueryContainerDescriptor <RoomDocument>, QueryContainer> >();
                var must_not           = new List <Func <QueryContainerDescriptor <RoomDocument>, QueryContainer> >();
                var should             = new List <Func <QueryContainerDescriptor <RoomDocument>, QueryContainer> >();
                var filter             = new List <Func <QueryContainerDescriptor <RoomDocument>, QueryContainer> >();
                int minimunShouldMatch = 0;

                must_not.Add(
                    mustNot => mustNot.HasChild <ReservationDocument>(hasChild => hasChild
                                                                      .Query(childQuery => childQuery.DateRange(childDateRange => childDateRange.Field(reservation => reservation.Date).GreaterThanOrEquals(arrival).LessThan(departure))
                                                                             ))
                    );


                if (terms != null && terms.Any())
                {
                    foreach (var term in terms)
                    {
                        filter.Add(filterQuery => filterQuery.Term(mustTerm => mustTerm.Field(term.Aggregation).Value(term.Term).Verbatim()));
                    }
                }

                if (!string.IsNullOrEmpty(text))
                {
                    text = text.TrimEnd('*') + '*';
                    should.Add(shouldQuery => shouldQuery.QueryString(queryString => queryString.Boost(2.0).Query(text).Fields(fields => fields.Field("roomName", 2.0).Field("hotelNameAnalyzed", 5.0))));

                    //If you wanted to do a fuzzy query you should do this instead
                    //should.Add(shouldQuery => shouldQuery.Match(match => match.Boost(5.0).Field(d => d.HotelNameAnalyzed).Fuzziness(Fuzziness.EditDistance(6)).Query(text)));
                    //should.Add(shouldQuery => shouldQuery.Match(match => match.Boost(2.0).Field(d => d.RoomName).Fuzziness(Fuzziness.EditDistance(6)).Query(text)));
                    minimunShouldMatch++;
                }

                if (maxPrice.HasValue)
                {
                    filter.Add(filterQuery => filterQuery.Range(range => range.Field(room => room.Price).LessThanOrEquals(Convert.ToDouble(maxPrice.Value))));
                }

                return(boolquery.Must(must).MustNot(must_not).Should(should).Filter(filter).MinimumShouldMatch(MinimumShouldMatch.Fixed(minimunShouldMatch)));
            }
                                                                                                                              ))))
                                                              );

            slimLock.ExitReadLock();
            sw.Stop();
            var result = new SearchResult
            {
                Aggregations = searchResponse.Aggregations.Select(aggr => new AggregationDTO {
                    Aggregation = aggr.Key, Terms = (aggr.Value as BucketAggregate).Items.Select(bucket => TermDTO.FromBucket(bucket)).Where(dto => dto != null && dto.DocumentCount > 0)
                }),
                TotalResults    = searchResponse.Total,
                QueryDuration   = searchResponse.Took,
                RequestDuration = sw.ElapsedMilliseconds,
                Hits            = searchResponse.Hits.Select(hit => new ResultDTO {
                    Room = hit.Source, Score = Convert.ToDecimal(hit.Score)
                })
            };

            return(result);
        }