0

I'm working on a project that searches parts using ElasticSearch and NEST (7.x). Here's my Model (adjusted for simplicity):

    [ElasticsearchType]
    public class PartInfo
    {
        public string Make { get; set; }
        public string PartNo { get; set; }
        public string Description { get; set; }
        public string WebURL { get; set; }
        public string Category { get; set; }
        public string[] Keywords { get; set; }
        public string[] FilterValue { get; set; }
        public int SalesYTD { get; set; }
        public bool IsDiscontinued { get; set; }
        public string PartClass { get; set; }
        [Ignore]
        public double? Score { get; set; }
    }

And the Index Creation routine (again edited for relevance):

        public void IndexParts(IEnumerable<PartInfo> parts)
        {
            var deleteIndexResponse = _client.Indices.Delete("partinfo");
            var createIndexResponse = _client.Indices.Create("partinfo", c => c.Map<PartInfo>(m => m.AutoMap()));
            int batch = 1000;
            foreach (var batches in parts.Batch(batch))
            {
                var response = _client.IndexMany(batches, "partinfo");
                if (!response.IsValid) throw new Exception("Error Indexing!");
            }
        }

And finally my search query:

            var filters = new List<Func<QueryContainerDescriptor<PartInfo>, QueryContainer>>();
            filters.Add(f => f.Match(m => m.Field(fi => fi.PartClass).Query(partClass)));
            if (!showDiscontinued) filters.Add(f => f.Term(m => m.Field(fi => fi.IsDiscontinued).Value(false)));

            var result = _client.Search<PartInfo>(x => x.Index("partinfo").Query(q => q
                .Bool(b => b
                    .Should(sh => sh
                        .MatchPhrasePrefix(m => m
                            .Field(fi => fi.PartNo)
                            .Query(query)
                            .Boost(100)
                        ),
                        sh => sh
                        .Term(m => m
                            .Field(f => f.Category)
                            .Value(query)
                            .Boost(100)
                        ),
                        sh => sh
                        .MatchPhrase(m => m
                            .Field(f => f.Category)
                            .Query(query)
                            .Boost(90)
                        ),
                        sh => sh
                        .MatchPhrase(m => m
                            .Field(fi => fi.Description)
                            .Query(query)
                            .Boost(10)
                        ),
                        sh => sh
                        .Term(t => t.Keywords, query, 10),
                        sh => sh
                    )
                    .Filter(filters)
                )
            )
            .From(page - 1).Size(pageSize));

Here's my two goals:

  1. I need to be able to search against PartNo OR Category first, followed by Description and/or Keywords. PartNo should be by prefix, while the other queries can be any combination of words.
  2. For the results, I need them returned by both score/relevance AND by SalesYTD top to bottom - together. For example, same scoring items get sorted by higher sales first.
Paulo
  • 8,690
  • 5
  • 20
  • 34
Michael
  • 507
  • 5
  • 20

0 Answers0