Elasticsearch.Net and multisearch

How do you perform a multisearch with Elasticsearch.Net? I cannot find any examples of this.

Here's an example using the fluent lambda API

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)
    )
);

And the same with the Object Initializer syntax

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 integration tests for another example: https://github.com/elastic/elasticsearch-net/blob/5.x/src/Tests/Search/MultiSearch/MultiSearchApiTests.cs#L52-L81

But this is using Nest right? I do not want to use Nest.

I found that you can use ElasticsearchClient.Msearch();

Yes, this is using NEST, the high level client.

To use Elasticsearch.Net low level client with multi search would be

var client = new ElasticLowLevelClient();

client.LowLevel.Msearch<dynamic>(new object[] {
	new { index = "products", type = "product"},
	new { 
		query = new { 
			@bool = new { 
				should = new object [] { 
					new { 
						multi_match = new { 
							type = "best_fields", 
							query = "product query", 
							fields = new [] { "name","name.raw" }
						}
					}
				}
			}
		}
	},
	new { index = "categories", type = "category"},
	new { 
		query = new { 
			@bool = new { 
				should = new object [] { 
					new { 
						multi_match = new { 
							type = "best_fields", 
							query = "category query", 
							fields = new [] { "name","name.raw" }
						}
					}
				}
			}
		}
	}
});

The dynamic generic type parameter on the method is the type into which the response will be deserialized into (which will be an internal JsonObject type when using dynamic).

The low level client by default supports string, byte[], Stream, object, or your own type. The low level client contains a simple json parser that will deserialize the response into an internal JsonObject that can be easily traversed when using dynamic (with all the caveats of bypassing static typing). If you need strongly typed responses, I'd recommend using NEST which exposes all requests and responses as strong types.

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.