Requête Min position par date

je cherche à récupérer pour une liste de mots, sa position min à la première date du filtre et sa position min à la dernière date du filtre . La requête suivante me retourne pour chaque mot et pour chaque date dans le filtre et j'ai mi un min_doc_count mais cela retourne toujours pour toute les dates .

une idée ?

merci

get ....../_search
{

 "query": {
"bool": {
  "must": [
    {
      "match": {
        "idsite": 12
      }
    },
    {
      "match": {
        "device": "DESKTOP"
      }
    }
  ],
  "filter": {
      "range": {
        "datecreation": {
          "gte": "2017-05-01",
          "lte": "2017-07-31"
          
        }
        
      }
    }
}
},
"aggs": {
"listekeyword": {
  "terms": {
    "field": "idkeyword.keyword",
    "size": 10
  },
  "aggs": {
    "listedatemin":{
      "date_histogram": {
        "field": "datecreation",
        "interval": "day",
        "order": [{"_key":"asc"}]
        
      },
      "aggs": {
        "position": {
          "avg": {
            "field": "position"
          }
        }
      }
     
    },
    "listedatemax":{
      "date_histogram": {
        "field": "datecreation",
        "interval": "day",
        "order": [{
          "_key": "desc"
        }]
      }
      , "aggs": {
        "positionmax": {
          "avg": {
            "field": "position"
          }
        }
      }
    }
    
   }
  }
 }
}

Peux-tu fournir un exemple complet que nous pouvons ensuite copier-coller dans Kibana pour reproduire ton problème puis éventuellement proposer une solution ?

L'exemple le plus simple possible est le mieux.

alors voila le résultat que j'obtiens actuellement mais cela me retourne trop de date dans les aggs listedatemax et listedatemin.

"aggregations": {
    "listekeyword": {
      "doc_count_error_upper_bound": 495,
      "sum_other_doc_count": 559302,
      "buckets": [
        {
          "key": "garde corps inox",
          "doc_count": 808,
          "listedatemax": {
            "buckets": [
              {
                "key_as_string": "2017-07-31T00:00:00.000Z",
                "key": 1501459200000,
                "doc_count": 25,
                "positionmax": {
                  "value": 51.40799991607666
                }
              },
              {
                "key_as_string": "2017-07-30T00:00:00.000Z",
                "key": 1501372800000,
                "doc_count": 27,
                "positionmax": {
                  "value": 49.94074081491541
                }
              },
              {
                "key_as_string": "2017-07-29T00:00:00.000Z",
                "key": 1501286400000,
                "doc_count": 10,
                "positionmax": {
                  "value": 41.24999990463257
                }
              }.....
 "listedatemin": {
            "buckets": [
              {
                "key_as_string": "2017-05-24T00:00:00.000Z",
                "key": 1495584000000,
                "doc_count": 11,
                "position": {
                  "value": 72.25454560193148
                }
              },
              {
                "key_as_string": "2017-05-25T00:00:00.000Z",
                "key": 1495670400000,
                "doc_count": 13,
                "position": {
                  "value": 35.31538460804866
                }
              },
              {
                "key_as_string": "2017-05-26T00:00:00.000Z",
                "key": 1495756800000,
                "doc_count": 10,
                "position": {
                  "value": 44.85999984741211
                }
              }...
              

je fais comment pour sortir un exemple , il y a une méthode ?

Oui. Tu ouvres Kibana. Tu vas dans le dev console et tu tapes un code qui permettra de reproduire entièrement ton problème. Tel que:

DELETE index
PUT index/_doc/1
{
  "foo": "bar"
}
GET index/_search
{
  "query": {
    "match": {
      "foo": "bar"
    }
  }
}
PUT name_index/_doc/1
{
   "idsite":1,
   "idkeyword":"maison",
   "datecreation":"2018-01-01",
  "position": 1.5
}
PUT name_index/_doc/2
{
   "idsite":1,
   "idkeyword":"maison",
   "datecreation":"2018-01-01",
  "position": 2
}
PUT name_index/_doc/3
{
   "idsite":1,
   "idkeyword":"maison",
   "datecreation":"2018-01-01",
  "position": 4
}

PUT name_index/_doc/5
{
   "idsite":1,
   "idkeyword":"maison",
   "datecreation":"2018-01-02",
  "position": 2
}

PUT name_index/_doc/6
{
   "idsite":1,
   "idkeyword":"maison",
   "datecreation":"2018-01-02",
  "position": 8
}

PUT name_index/_doc/7
{
   "idsite":1,
   "idkeyword":"maison",
   "datecreation":"2018-01-02",
  "position": 9
}



get ....../_search
{

 "query": {
"bool": {
  "must": [
    {
      "match": {
        "idsite": 1
      }
    }
   
  ],
  "filter": {
      "range": {
        "datecreation": {
          "gte": "2018-01-01",
          "lte": "2018-01-02"
          
        }
        
      }
    }
}
},
"aggs": {
"listekeyword": {
  "terms": {
    "field": "idkeyword.keyword",
    "size": 10
  },
  "aggs": {
    "listedatestart":{
      "date_histogram": {
        "field": "datecreation",
        "interval": "day",
        "order": [{"_key":"asc"}]
        
      },
      "aggs": {
        "position": {
          "avg": {
            "field": "position"
          }
        }
      }
     
    },
    "listedateend":{
      "date_histogram": {
        "field": "datecreation",
        "interval": "day",
        "order": [{
          "_key": "desc"
        }]
      }
      , "aggs": {
        "positionmax": {
          "avg": {
            "field": "position"
          }
        }
}

dc cela doit me donner la moyenne position pour le 2018-01-01 and pour le 2018-01-02 mais de manière auto si demain dans le range filter je change les date la requête doit pouvoir savoir le start et le end en auto .

le top serais que la requête soit capable de dire true ou false si la position moyenne à la start date est supérieur à la position moyenne à la date end :slight_smile:

Je doute que tu aies essayé de jouer ce que tu as publié dans Kibana.
La syntaxe est fausse.

J'ai refait le début pour avoir un truc propre:

DELETE name_index
PUT name_index/_doc/1
{
  "idsite": 1,
  "idkeyword": "maison",
  "datecreation": "2018-01-01",
  "position": 1.5
}
PUT name_index/_doc/2
{
  "idsite": 1,
  "idkeyword": "maison",
  "datecreation": "2018-01-01",
  "position": 2
}
PUT name_index/_doc/3
{
  "idsite": 1,
  "idkeyword": "maison",
  "datecreation": "2018-01-01",
  "position": 4
}
PUT name_index/_doc/5
{
  "idsite": 1,
  "idkeyword": "maison",
  "datecreation": "2018-01-02",
  "position": 2
}
PUT name_index/_doc/6
{
  "idsite": 1,
  "idkeyword": "maison",
  "datecreation": "2018-01-02",
  "position": 8
}
PUT name_index/_doc/7
{
  "idsite": 1,
  "idkeyword": "maison",
  "datecreation": "2018-01-02",
  "position": 9
}
GET name_index/_search

Je te laisse mettre à jour la partie Search qui ne passe pas dans Kibana et vu l'indentation de ton code, c'est illisible pour tenter un temps soit peu de le réécrire rapidement.

GET name_index/_doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "idsite": 1
          }
        }
      ],
      "filter": {
        "range": {
          "datecreation": {
            "gte": "2018-01-01",
            "lte": "2018-01-02"
          }
        }
      }
    }
  },
  "aggs": {
    "listekeyword": {
      "terms": {
        "field": "idkeyword.keyword",
        "size": 10
      },
      "aggs": {
        "listedatestart": {
          "date_histogram": {
            "field": "datecreation",
            "interval": "day",
            "order": [
              {
                "_key": "asc"
              }
            ]
          },
          "aggs": {
            "position": {
              "avg": {
                "field": "position"
              }
            }
          }
        },
        "listedateend": {
          "date_histogram": {
            "field": "datecreation",
            "interval": "day",
            "order": [
              {
                "_key": "desc"
              }
            ]
          },
          "aggs": {
            "positionmax": {
              "avg": {
                "field": "position"
              }
            }
          }
        }
      }
    }
  }
}

Donc ton exemple donne:

{
  "took": 16,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 6,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "listekeyword": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "maison",
          "doc_count": 6,
          "listedatestart": {
            "buckets": [
              {
                "key_as_string": "2018-01-01T00:00:00.000Z",
                "key": 1514764800000,
                "doc_count": 3,
                "position": {
                  "value": 2.5
                }
              },
              {
                "key_as_string": "2018-01-02T00:00:00.000Z",
                "key": 1514851200000,
                "doc_count": 3,
                "position": {
                  "value": 6.333333333333333
                }
              }
            ]
          },
          "listedateend": {
            "buckets": [
              {
                "key_as_string": "2018-01-02T00:00:00.000Z",
                "key": 1514851200000,
                "doc_count": 3,
                "positionmax": {
                  "value": 6.333333333333333
                }
              },
              {
                "key_as_string": "2018-01-01T00:00:00.000Z",
                "key": 1514764800000,
                "doc_count": 3,
                "positionmax": {
                  "value": 2.5
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Pour mieux comprendre, peux-tu dire à peu près quel résultat concret tu aimerais voir ?

"listedatestart": {
            "buckets": [
              {
                "key_as_string": "2018-01-01T00:00:00.000Z",
                "key": 1514764800000,
                "doc_count": 3,
                "position": {
                  "value": 2.5
                }
              }
            ]
          }

"listedateend": {
            "buckets": [
              {
                "key_as_string": "2018-01-02T00:00:00.000Z",
                "key": 1514851200000,
                "doc_count": 3,
                "positionmax": {
                  "value": 6.333333333333333
                }
              }
            ]
          }

juste avoir dans les aggs listedatend et start 1 seul date . La date de debut du range pour le premier et la date de fin du range pour la seconde

Est-ce que ajouter un min agg et un max agg sur datecreation marcherait ?

j'ai l'erreur

Aggregator [listedatestart] of type [min] cannot accept sub-aggregations

car après je veut avoir la moyenne position sur cette date min mais min ne supporte pas de sub-aggregations

Non. Ca tu ne peux pas.
Mais peut-être qu'avec le pipeline aggregation tu peux t'en sortir???

Je ne sais pas. @jimczi ou @jpountz ont peut être une idée ?

j'ai essayé" cela, mais cela retourne un min sur position et pas un min sur la date

 "minbucket":{
          "min_bucket": {
            "buckets_path": "listedatestart>position"
          }
        }
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "idsite": 1
          }
        }
      ],
      "filter": {
        "range": {
          "datecreation": {
            "gte": "2018-01-01",
            "lte": "2018-01-05"
          }
        }
      }
    }
  },
  "aggs": {
    "listekeyword": {
      "terms": {
        "field": "idkeyword.keyword",
        "size": 10
      },
      "aggs": {
        "posdayone":{
          "filter": {
            "term": {
              "datecreation": "2018-01-01"
            }
          },
          "aggs": {
            "position": {
              "avg": {
                "field": "position"
              }
            }
          }
        },
        "posdayend":{
          "filter": {
            "term": {
              "datecreation": "2018-01-05"
            }
          },
          "aggs": {
            "position": {
              "avg": {
                "field": "position"
              }
            }
          }
        },
        "evolution":{
          "bucket_script": {
            "buckets_path": {
              "dayone":"posdayone>position",
              "dayend":"posdayend>position"
              },
            "script":"if (params.dayend<params.dayone) {1} else {0} "
          }
        }
      
      }
    }
  }
}

sa semble pas mal :slight_smile:

Salut,

Juste pour information, si tu fais plein d'aggregations et de sous aggregations tu peux faire planter ton serveur, :sweat_smile: ca m'est arrivé.
Si ton server crash et que t'as: "java.lang.OutOfMemoryError: Java heap space" dans tes logs c'est peut etre a cause de ca.
Verifie bien la memoire "heap" avec tes donnees de production.

De mémoire il y a maintenant le circuit breaker qui s'applique aussi aux aggregations et qui devrait éviter de planter le serveur.
Néanmoins tu as raison car ça renverra quand même une erreur (mais plus propre qu'un OOM). :wink:

je confirme j'ai bien crasher le serveur lol trop de aggs tue les aggs :slight_smile:

1 Like

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