1
votes

I need to create the query dynamically. I have a list of terms with their weights in a hashtable that the number of terms varies. I want to search these terms in the content of an amount of documents and boost each words according to its weight. Something similar to the code below:

var searchResults = client.Search<Document>(s => s.Index(defaultIndex)
 .Query(q => q.Match(m => m.OnField(p => p.File).Query(term1).Boost(term1.weight).Query(term2).Query(term2.weight)...Query(term N ).Boost(termN.weight))))

The only solution that I found is to use "Raw String" like the example in the link http://nest.azurewebsites.net/nest/writing-queries.html

.QueryRaw(@"{""match_all"": {} }")
.FilterRaw(@"{""match_all"": {} }")

Since I don't know how many terms exist each time, how can I handle such a problem? Does anyone know another solution rather than "Raw strings"? I am using C# Nest Elasticsearch.

Here is a sample of JSON Elasticsearch query for such a case:

GET  testindex2/document/_search
{
  "query": {
   "bool": {
    "should": [
    {
      "match": {
        "file": {
          "query": "kit",
          "boost": 3
        }
      }
    },
    {
      "match": {
        "file": {
          "query": "motor",
          "boost": 2.05
        }
      }
    },
    {
      "match": {
        "file": {
          "query": "fuel",
          "boost": 1.35
        }
      }
    }
  ]
}

} }

1
Can you mention the expected Elasticsearch JSON query? - bittusarkar
Sure, I added it. Please see the edit in my question. - Mahsa
I posted the answer to your question. Do mark it as answer if it fixed your problem :) - bittusarkar
Many thanks bittusarkar for your answer. - Mahsa

1 Answers

2
votes

You need to create a Bool Should query and pass an array of QueryContainer objects which can be generated dynamically. I've written a small code snippet that will build the Nest query as per your requirements. Simply update the Dictionary boostValues and you should be good to go.

var boostValues = new Dictionary<string, double>
{
    { "kit", 3 },
    { "motor", 2.05 },
    { "fuel", 1.35 }
};

var qc = new List<QueryContainer>();
foreach (var term in boostValues)
{
    qc.Add(
        Query<Document>.Match(m => m
            .OnField(p => p.File)
            .Boost(term.Value)
            .Query(term.Key)));
}

var searchResults = client.Search<Document>(s => s
    .Index(defaultIndex)
    .Query(q => q
        .Bool(b => b
            .Should(qc.ToArray()))));