コード例 #1
0
        public async Task MultiMatch()
        {
            var lookingFor = "jp morgan";

            var searchResponse = await ElasticClient().SearchAsync <Branch>(s => s
                                                                            .Query(q => q.MultiMatch(mm => mm
                                                                                                     .Query(lookingFor)
                                                                                                     //show minimum should match
                                                                                                     .MinimumShouldMatch(MinimumShouldMatch.Percentage(100.0))
                                                                                                     .Fields(f => f
                                                                                                             .Fields(ff => ff.LocationName, ff => ff.LocationContact)))));

            searchResponse.IsValid.ShouldBe(true);
        }
        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   = (int)searchResponse.Took,
                RequestDuration = sw.ElapsedMilliseconds,
                Hits            = searchResponse.Hits.Select(hit => new ResultDTO {
                    Room = hit.Source, Score = Convert.ToDecimal(hit.Score)
                })
            };

            return(result);
        }