J'ai une demande dans Elastic

{  
   "query":{  
      "bool":{  
         "must":[  
            {  
               "query_string":{  
                  "query":"something1 OR something2 OR something3",
                  "default_operator":"OR"
               }
            }
         ],
         "filter":{  
            "range":{  
               "time":{  
                  "gte":date
               }
            }
         }
      }
   }
}

Je veux calculer le nombre pour chaque jeton dans tous les documents à l'aide de la recherche élastique dans une seule demande, par exemple:

something1: 26 documents
something2: 12 documents
something3: 1 documents
1
Саша Коровій 20 nov. 2018 à 13:21

3 réponses

Meilleure réponse

En supposant que les jetons ne s'apparentent pas à des énumérations (c'est-à-dire à un ensemble contraint de valeurs spécifiques, comme les noms d'état, ce qui ferait un termes agrégation votre meilleur pari avec le bon mappage), je pense que la chose la plus proche de ce que vous voulez serait d'utiliser agrégation de filtres:

POST your-index/_search
{
  "query":{  
    "bool":{  
      "must":[  
      {  
        "query_string":{  
          "query":"something1 OR something2 OR something3",
          "default_operator":"OR"
         }
      }
      ],
      "filter":{  
        "range":{  
          "time":{  
            "gte":date
          }
        }
      }
    }
  },
  "aggs": {
    "token_doc_counts": {
      "filters" : {
        "filters" : {
          "something1" : { 
            "bool": { 
              "must": { "query_string" : { "query" : "something1" } }, 
              "filter": { "range": { "time": { "gte": date } } } 
            }
          },
          "something2" : { 
            "bool": { 
              "must": { "query_string" : { "query" : "something2" } }, 
              "filter": { "range": { "time": { "gte": date } } } 
            }
          },
          "something3" : { 
            "bool": { 
              "must": { "query_string" : { "query" : "something3" } }, 
              "filter": { "range": { "time": { "gte": date } } } 
            }
          }
        }
      }
    } 
  }
}

La réponse ressemblerait à quelque chose comme:

{
  "took": 9,
  "timed_out": false,
  "_shards": ...,
  "hits": ...,
  "aggregations": {
    "token_doc_counts": {
      "buckets": {
        "something1": {
          "doc_count": 1
        },
        "something2": {
          "doc_count": 2
        },
        "something3": {
          "doc_count": 3
        } 
      } 
    } 
  }
}
1
mike b 20 nov. 2018 à 22:22

Vous pouvez diviser votre requête en filtres d'agrégation de trois filtres. Pour référence, regardez ici: https : //www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html

0
Opster ES Ninja Nishant 20 nov. 2018 à 11:01

Ce que vous devez faire, c'est créer un Copy_To et ayez le mappage comme indiqué ci-dessous.

Selon les champs que votre query_string interroge, vous devez inclure certains ou all des champs avec le champ copy_to.

Par défaut, query_string recherche tous les champs, vous devrez peut-être spécifier copy_to pour tous les champs comme indiqué dans le mappage ci-dessous, où par souci de simplicité, je n'ai créé que trois champs, {{X2 }}, field_2 et un troisième champ content qui ferait office de champ copié dans .

Cartographie

PUT <your_index_name>
{
  "mappings": {
    "mydocs": {
      "properties": {
        "title": {
          "type": "text",
          "copy_to": "content" 
        },
        "field_2": {
          "type": "text",
          "copy_to": "content" 
        },
        "content": {
          "type": "text",
          "fielddata": true
        }
      }
    }
  }
}

Exemples de documents

POST <your_index_name>/mydocs/1
{
  "title": "something1",
  "field_2": "something2"
}

POST <your_index_name>/mydocs/2
{
  "title": "something2",
  "field_2": "something3"
}

Requete:

Vous obtiendrez le nombre de documents requis pour chaque jeton à l'aide de la requête d'agrégation ci-dessous et j'ai utilisé Agrégation des termes:

POST <your_index_name>/_search
{
  "size": 0,
  "query": {
    "query_string": {
      "query": "something1 OR something2 OR something3"
    }
  },
  "aggs": {
    "myaggs": {
      "terms": {
        "field": "content",
        "include" : ["something1","something2","something3"]
      }
    }
  }
}

Réponse à la requête:

{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "myaggs": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "something2",
          "doc_count": 2
        },
        {
          "key": "something1",
          "doc_count": 1
        },
        {
          "key": "something3",
          "doc_count": 1
        }
      ]
    }
  }
}

Faites-moi savoir si cela aide!

0
Opster ES Ninja - Kamal 20 nov. 2018 à 15:50