Combine two queries

I need to combine 2 queries and I am not sure how to do it. I have one field which has site names (we have few properties that I am scraping and putting cleaned html from it into Elastic Search) and few other fields (content, description, etc). So when I search I would like to search for specific site and then search for keywords in other fields. How would I get around doing this?

Here is the mapping

{
  "media": {
    "aliases": {},
    "mappings": {
      "articles": {
        "properties": {
          "author": {
            "type": "keyword"
          },
          "cmskeywords": {
            "type": "text"
          },
          "content": {
            "type": "text",
            "analyzer": "lowercasespaceanalyzer"
          },
          "description": {
            "type": "text"
          },
          "imageUrl": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "imageurl": {
            "type": "keyword"
          },
          "partNumbers": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "partnumbers": {
            "type": "keyword"
          },
          "pubdate": {
            "type": "date"
          },
          "relatedcontentwords": {
            "type": "text"
          },
          "site": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "title": {
            "type": "text"
          },
          "url": {
            "type": "keyword"
          }
        }
      }
    },
    "settings": {
      "index": {
        "number_of_shards": "5",
        "provided_name": "media",
        "creation_date": "1522284975992",
        "analysis": {
          "analyzer": {
            "lowercasespaceanalyzer": {
              "filter": [
                "lowercase"
              ],
              "type": "custom",
              "tokenizer": "whitespace"
            }
          }
        },
        "number_of_replicas": "1",
        "uuid": "Qz8JbotxQee6Dihll3uBSQ",
        "version": {
          "created": "6020299"
        }
      }
    }
  }
}

Here are 2 DSL queries 

{
  "query": {
    "match": {
      "site": {
        "query": "EBN",
        "type": "phrase"
      }
    }
  }

{
  "query": {
    "match": {
      "site": {
        "query": "EBN",
        "type": "phrase"
      }
    }
  }

You can combine the queries using bool query. Based on your requirement you can use 'should' or 'must' inside the bool clauses.

You may want to schearch for both the field you want, and then aggregate by the most important field.

Sravanthi_N_S_CH,

I am not sure how I would combine those. I wrote one of those but I don't think it's working. Here is what I wrote.

 mediaResponse = elastic.Search<Articles>(s => s
            .Pretty(true)
            .Human(true)
            .Index(mediaIndexName)
            .Type(mediaTypeName)
            .From(DefaultPageNumber)
            .Size(numResults)
            .Query(q => q
                .Bool(
                    sm => sm.Should(
                        m => m.Match(f => f.Field(fn => fn.Site)
                                            .Query(SiteName))
                        ).Filter(fc => fc.MultiMatch(mm => mm.Fields(
                                 f => f
                                         .Field(fn => fn.Title)
                                         .Field(fn => fn.Content)
                                         .Field(fn => fn.Description)
                                         .Field(fn => fn.PartNumbers)
                                          .Field(fn => fn.Site)
                             ).Query(queryTxt))))
                && q.DateRange(dr => dr.Field(f => f.Pubdate).GreaterThanOrEquals(StartDate).LessThanOrEquals(EndDate))
             ).Sort(x => x.Descending(y => y.Pubdate)));

If your use case is to filter the content based on Sitename, title and content etc..
you can try something like

{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
           "must": [
             {
               "term": {
          "SITENAME.keyword": "true"
        }
             },
             {
               "term": {
            "title.keyword": {
              "value": "true"
            }
          }
             }
             ]
        }
      }
    }
  }
}

If this is not what you are looking for, can you please give more details about what your requirements are

I will give this a try and see the NEST converted query works.

Thanks

Hi @Sravanthi_N_S_CH how does the sitename.keyword (or for that matter any field.keyword) translate to NEST?

@subrato You can use either a string

.Field("sitename.keyword")

or an expression

.Field(f => f.Sitename.Suffix("keyword"))

Take a look at the documentation on field inference.

Hi I dont think I understood what you were trying to say and was wondering if you take a look at the code and see what is missing (I know something is missing, one of them obviously me not assigning the values but not sure where to assign them in the query format you mentioned)

 var mediaResponse = elastic.Search<Articles>(s => s
            .Pretty(true)
            .Human(true)
            .Index(mediaIndexName)
            .Type(mediaTypeName)
            .From(pageNumber)
            .Size(numResults)
            .Query(
                q => q.ConstantScore(
                    filter => filter.Filter(b => b.Bool(
                          m => m.Must(t => t.Term(f => f.Field(fn => fn.Site.Suffix("keyword")
                     ).Field(fn => fn.Content))))))));

Where do I assign the values that I want to match to for site & content.

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