Code Monkey home page Code Monkey logo

Comments (5)

MarkMcDonald avatar MarkMcDonald commented on June 16, 2024

Been covering this myself and been very reliant on the source code to guide. If it helps though I can share the approach we've been using to refactor existing code.

As far as I can make out the concept of ANDs and ORs you had in the NEST client has been remove - and I actually I think this may be a good thing because I don't think they exist conceptually in the search language.

So below is an example of how we refactored from using the operators to Action delegates so we didn't have to refactor existing if statements to much, same can be done with for statements and sorts and other things.

        private static Action<QueryDescriptor<MySearchModel>> BuildQuery([NotNull] MyRequest request)
        {
            var musts = new List<Action<QueryDescriptor<MySearchModel>>>();
            var mustNots = new List<Action<QueryDescriptor<MySearchModel>>>();
            var shoulds = new List<Action<QueryDescriptor<MySearchModel>>>();

            if (request.TagIds?.Any() ?? false)
            {
                musts
                    .Add(m => m
                        .Terms(t => t
                            .Field(f => f.Tags)
                            .Terms(new TermsQueryField(request.TagIds.Select(x => FieldValue.Long(x)).ToArray()))
                        )
                    );
            }

            if (request.DocumentTypeId != null && request.DocumentTypeId != 0)
            {
                musts
                    .Add(m => m
                        .Term(t => t
                            .Field("docTypeId")
                            .Value(FieldValue.Long(request.DocumentTypeId ?? 0))
                        )
                    );
            }

            mustNots
                .Add(m => m
                    .Term(t => t
                        .Field(f => f.HideInSearchResults)
                        .Value(FieldValue.Boolean(true))
                    )
                );

            if (request.ExcludedDocumentTypeIds != null && (request.ExcludedDocumentTypeIds?.Any() ?? false))
            {
                mustNots
                    .Add(m => m
                        .Terms(t => t
                            .Field("docTypeId")
                            .Terms(new TermsQueryField(request.ExcludedDocumentTypeIds.Select(x => FieldValue.Long(x)).ToArray()))
                        )
                    );
            }
            if (request.ExcludedPageIds != null && (request.ExcludedPageIds?.Any() ?? false))
            {
                mustNots
                    .Add(m => m
                        .Terms(t => t
                            .Field("id")
                            .Terms(new TermsQueryField(request.ExcludedPageIds.Select(x => FieldValue.Long(x)).ToArray()))
                        )
                    );
            }

            if (request.PrimaryTagId.HasValue && request.PrimaryTagId != 0)
            {
                shoulds
                    .Add(s => s
                        .Term(t => t
                            .Field("primaryTagId")
                            .Value(FieldValue.Long(request.PrimaryTagId.Value))
                        )
                    );
            }

            return query => query
                .Bool(b => b
                    .Must(musts.ToArray())
                    .MustNot(mustNots.ToArray())
                    .Should(shoulds.ToArray())
                );
        }

We can then refactor / create the search result descriptor as below:

                Action<SearchRequestDescriptor<MySearchModel>> searchRequest = s => s
                                        .Index("my-index")
                                        .Query(BuildQuery(request))
                                        .Sort(s => s.Field(f => f.UpdatedOn, fs => fs.Order(SortOrder.Desc)))
                                        .From(0)
                                        .Size(20);

Multiple sorting fields can be addressed in a similar manner:

        private static Action<SortOptionsDescriptor<MySearchModel>>[] BuildSort(string sortOption)
        {
            return sortOption.ToLower() switch
            {
                "sort2" => new Action<SortOptionsDescriptor<MySearchModel>>[]
                    {
                        s => s.Field(f => f.MyField1, fs => fs.Order(SortOrder.Asc)),
                        s => s.Field(f => f.MyField2, fs => fs.Order(SortOrder.Desc)),
                    },
                "sort3" => new Action<SortOptionsDescriptor<MySearchModel>>[]
                    {
                        s => s.Field(f => f.MyField3, fs => fs.Order(SortOrder.Desc)),
                        s => s.Score(new ScoreSort() { Order = SortOrder.Desc })
                    },
                _ => new Action<SortOptionsDescriptor<MySearchModel>>[]
                    {
                        s => s.Field(f => f.MyField4, fs => fs.Order(SortOrder.Desc)),
                        s => s.Field(f => f.Dates.FirstOrDefault().StartDate, fs => fs.Order(SortOrder.Asc)),
                        s => s.Field(f => f.Dates.FirstOrDefault().EndDate, fs => fs.Order(SortOrder.Asc)),
                    },
            };
        }

Your Sort line would then become:

                Action<SearchRequestDescriptor<MySearchModel>> searchRequest = s => s
                                        .Index("my-index")
                                        .Query(BuildQuery(request))
                                        .Sort(BuildSort(sortOption))
                                        .From(0)
                                        .Size(20);

I can't vouch if this is 100% the approach that should be taken. The documentation is very thin on client usage, and doesn't seem to be up to date with the source code or NuGet packages. But it is working for us so far.

Based on using upgrading from NEST 7.17.5 to Elastic.Clients.Elasticsearch 8.13.12.

Hope people find this helpful.

from elasticsearch-net.

franquiroz avatar franquiroz commented on June 16, 2024

Hi @MarkMcDonald, Thanks so much for your reply. I understand that my current code does not have a solution in the new DLL, for me it is not viable make a migration because my project is very big and a have a lot of indexes with dynamic querys and nested querys... i'm really disapointed and indignant....

by the way, do you know something about my first question about Analysis templates?

thx again!!

from elasticsearch-net.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.