Emil
Emil

Reputation: 6893

Nest multisearch query writing as object initializer Syntax

I have a multiSearch query as below. Basically I query product and category types. I would like to make this query optional without writing same code again. Basically in some cases I want to query only product type, that means that it will not multisearch but a search query. How can I split this query into 2 search queries. Something like below I think.

    return Client.MultiSearch(ms => ms
        .Search<Product>("products", s => s
        .Index(IndexName)
        .Explain(explain)
          .Query(q => q
             .Bool(b => b
                 .Should(
                     sh => sh.MultiMatch(qs => qs
                         .Fields(d => d                         
                             .Field(Name + ".raw", NameBoost + 0.5)
                             .Field(Name, NameBoost)                            
                            .Type(TextQueryType.BestFields)
                            .Query(key))
                            ))).From(startfrom).Size(size))
.Search<Category>("categories", s => s
.Index(IndexName)
.Explain(explain)
.Query(q => q.
Bool(b => b.
Should(sh => sh.
MultiMatch(m => m
.Fields(d => d
.Field(f => f.Name, NameBoost)
.Field(p => p.Name.Suffix("raw"), NameBoost + 0.5)).Type(TextQueryType.BestFields)
.Query(key)
)
))).From(startfrom).Size(size))
);

something like this below. I guess that it is called object initializer Syntax according to this article

Client.MultiSearch (SearchProductQuery && SearchCategoryQuery)

is it possible?

Upvotes: 3

Views: 3130

Answers (1)

Russ Cam
Russ Cam

Reputation: 125498

This fluent API multi search

client.MultiSearch(ms => ms
    .Search<Product>("products", s => s
        .Index(IndexName)
        .Explain(explain)
        .Query(q => q
           .Bool(b => b
                .Should(sh => sh
                    .MultiMatch(qs => qs
                        .Fields(d => d
                            .Field(Name + ".raw", NameBoost + 0.5)
                            .Field(Name, NameBoost)
                        )
                        .Type(TextQueryType.BestFields)
                        .Query(key)
                    )
                )
            )
        )
        .From(startfrom)
        .Size(size)
    )
    .Search<Category>("categories", s => s
        .Index(IndexName)
        .Explain(explain)
        .Query(q => q
            .Bool(b => b
                .Should(sh => sh
                    .MultiMatch(m => m
                        .Fields(d => d
                            .Field(f => f.Name, NameBoost)
                            .Field(p => p.Name.Suffix("raw"), NameBoost + 0.5)
                        )
                        .Type(TextQueryType.BestFields)
                        .Query(key)
                    )
                )
            )
        )
        .From(startfrom)
        .Size(size)
    )
);

would be this OIS API multi search

var multiSearch = new MultiSearchRequest
{
    Operations = new Dictionary<string, ISearchRequest>
    {
        { "products", new SearchRequest<Product>(IndexName)
            {
                Explain = true,
                Query = new BoolQuery
                {
                    Should = new QueryContainer[] {
                        new MultiMatchQuery
                        {
                            Fields = 
                                ((Fields)Field.Create(Name + ".raw", NameBoost + 0.5))
                                .And(Name, NameBoost),
                            Type = TextQueryType.BestFields,
                            Query = key
                        }
                    }
                },
                From = startfrom,
                Size = size
            }
        },
        { "categories", new SearchRequest<Category>(IndexName)
            {
                Explain = true,
                Query = new BoolQuery
                {
                    Should = new QueryContainer[] {
                        new MultiMatchQuery
                        {
                            Fields =    
                                ((Fields)Infer.Field<Category>(f => f.Name, NameBoost))
                                .And<Category>(f => f.Name.Suffix("raw"), NameBoost + 0.5),
                            Type = TextQueryType.BestFields,
                            Query = key
                        }
                    }
                },
                From = startfrom,
                Size = size
            }
        },
    }
};

client.MultiSearch(multiSearch);

Take a look at the multi search integration tests for another example. I'll look at getting this added to the documentation.

Upvotes: 5

Related Questions