Search code examples
c#elasticsearchnest

Elasticsearch / Nest search using MultiMatch with default boosting for all other fields


I'm trying to build a query that basically searches over all full text fields, boosting a few, but leaving all others at the default boost of 1.

When I don't include any fields, everything has a boost of 1 (we're on version 6.4.2 which supports default when no fields are specified):

var results = await _ElasticClient.SearchAsync<dynamic>(s => s
    .Query(q => q
        .MultiMatch(m => m
            .Query(request.Query)
        )
    )
);

However, as soon as I try to boost a single field, it removes the defaults on all the other fields, only searching on the explicit field:

var results = await _ElasticClient.SearchAsync<dynamic>(s => s
    .Query(q => q
        .MultiMatch(m => m
            .Fields(f => f.Field("firstName^20"))
            .Query(request.Query)
        )
    )
);

I tried adding a wildcard, but this still just matches on firstName (then again, the wildcard on its own doesn't match anything, so assuming I have the syntax wrong on that):

var results = await _ElasticClient.SearchAsync<dynamic>(s => s
    .Query(q => q
        .MultiMatch(m => m
            .Fields(f => f.Field("*.*^1"))
            .Fields(f => f.Field("firstName^20"))
            .Query(request.Query)
        )
    )
);

I also tried Booling them together, but this also just matches on firstName:

var results = await _ElasticClient.SearchAsync<dynamic>(s => s
    .Query(q => q
        .Bool(b => b
            .Should(m => m
                .MultiMatch(mm => mm
                    .Query(request.Query)
                )
            )
            .Should(m => m
                .MultiMatch(mm => mm
                    .Fields(f => f.Field("firstName^20"))
                    .Query(request.Query)
                )
            )
        )
    )
);

I'm starting to think this isn't possible. For context, the reason I'm trying to do this is to be able to add other full text fields to the index without having to include every field in our queries, but still be able to boost certain fields.


Solution

  • Figured out my problem. I was chaining multiple .Fields() (plural) together, where I should only have a single .Fields() (plural) and then chain multiple .Field() (singular) together:

    var results = await _ElasticClient.SearchAsync<dynamic>(s => s
        .Query(q => q
            .MultiMatch(m => m
                .Fields(f => f
                    .Field("firstName^20")
                    .Field("*.*^1")
                )
                .Query(request.Query)
            )
        )
    );