Home > Software engineering >  How to query elastic search with Hashmap
How to query elastic search with Hashmap

Time:01-25

I would like to query the Elastic Search with map of values and retrieve the documents.

Example: I have indexed the below two documents

 1. {
      "timestamp": 1601498048,
      "props": {
        "cp1": "cv1",
        "cp2": "cv2"
      }
    }

2. {
      "timestamp": 1601498098,
      "props": {
        "key1": "v1",
        "key2": "v2"
      }
    }

So, I wanted to query with the entire map values props with

"props" 
  {
     "cp1": "cv1",
     "cp2": "cv2"
 }

and return documents only for the entired matched map values. So in this case the result would be only first document, since it matched the given props.

I can able to query with only single map value like below , but need to search for entire map.

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {        
 "bool" : {
   "must" : [
     {                    
     "terms" : {
       "customProperties.cp1.keyword" : [ "cv1" ]
     }
    }
    ]
 }
 }
}
'

So how we query for entire map props and return documents only if all map key-values matched.

Update Mainly I need a QueryBuilder to search with map of values. I could do for set of values like below

val sampleSet = setOf("foo", "bar")

val query = NativeSearchQueryBuilder()
           .withQuery(
               QueryBuilders.termsQuery(
                   "identifiers.endpointId.keyword", sampleSet)
            )
            .build()

I need QueryBuilder to search with map of values in the ES index and return document only if entire map values matches.

Suggestions please.

CodePudding user response:

you must apply double match clausule.

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "props.cp1": "cv1"
          }
        },
        {
          "match": {
            "props.cp2": "cv2"
          }
        }
      ]
    }
  }
}

Or Term.

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "props.cp1.keyword": "cv1"
          }
        },
        {
          "term": {
            "props.cp2.keyword": "cv2"
          }
        }
      ]
    }
  }
}

CodePudding user response:

This worked. I just looped through the queryBuilder with map values props.

 val builder = QueryBuilders.boolQuery()
    
    for (prop in props) {
        builder.must(QueryBuilders.matchQuery("customProperties.${prop.key}", prop.value))
    }
    
    val query = NativeSearchQueryBuilder().withQuery(builder)
    
    println("results   $queryForList(query)")

passed query to this function

  internal fun queryForList(query: NativeSearchQuery): List<DocumentType> {
      val resp = searchOperations.search(query, type, IndexCoordinates.of(indexName))
      return resp.searchHits.map { it.content }
  }
         
  • Related