ElasticSearch – Returnarea valorilor unice (Programare, Elasticsearch)

ChuckJHardy a intrebat.

Cum aș putea obține valorile tuturor languages din înregistrări și să le fac unice.

Înregistrări

PUT items/1
{ "language" : 10 }

PUT items/2
{ "language" : 11 }

PUT items/3
{ "language" : 10 }

Interogare

GET items/_search
{ ... }

# => Expected Response
[10, 11]

Orice ajutor ar fi minunat.

Comentarii

  • fields: [languages] va oferi doar valorile câmpului dat, dar este probabil mai ușor să le faci unice în cod. Deși s-ar putea să existe o agregare la îndemână care să o facă pentru dvs. –  > Por Ashalynd.
  • Pentru cei care cercetează acest subiect, există, de asemenea, o discuție utilă aici : Găsiți valori distincte, nu numere distincte în elasticsearch –  > Por blong.
6 răspunsuri
Anton

Puteți utiliza Agregarea termenilor.

{
"size": 0,
"aggs" : {
    "langs" : {
        "terms" : { "field" : "language",  "size" : 500 }
    }
}}

Pe size din cadrul agregării specifică numărul maxim de termeni care trebuie incluși în rezultatul agregării. Dacă aveți nevoie de toate rezultatele, setați acest parametru la o valoare mai mare decât numărul de termeni unici din datele dumneavoastră.

O căutare va returna ceva de genul

{
"took" : 16,
"timed_out" : false,
"_shards" : {
  "total" : 2,
  "successful" : 2,
  "failed" : 0
},
"hits" : {
"total" : 1000000,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
  "langs" : {
    "buckets" : [ {
      "key" : "10",
      "doc_count" : 244812
    }, {
      "key" : "11",
      "doc_count" : 136794
 
    }, {
      "key" : "12",
      "doc_count" : 32312
       } ]
    }
  }
}

Comentarii

  • "fields" : ["language"] aduce același rezultat. Puteți să dezvoltați răspunsul dumneavoastră pentru a vedea dacă cadrul de agregare poate returna doar valorile limbii? #=> [10, 11, 10] –  > Por ChuckJHardy.
  • @CharlesJHardy, nu are același rezultat. Datele pe care le căutați se află sub cheia „aggregations”. Mi-am editat răspunsul cu un exemplu de rezultat. Puteți/ar trebui să setați și „size”: 0, pentru a nu include niciunul dintre documente, ci doar rezultatele agregate pe care le-ați dorit. –  > Por Anton.
  • Rețineți că, dacă aveți mai multe valori posibile pentru language ar fi bine să adăugați size=0 și shard_size=0, , pentru a vă asigura că obțineți toate valori. A se vedea elasticsearch.org/guide/en/elasticsearch/reference/current/… –  > Por Dror.
  • Cred că acest răspuns nu se adresează OP. Întrebarea inițială dorește o întrebare distinctă valori distincte nu numărători. Îmi scapă ceva? –  > Por bhurlow.
  • @BHBHBH, Răspunsul oferă valorile distincte. Acestea sunt valorile „cheie”, adică „10”, „11” și „12”. (aggregations > langs > buckets > key…) –  > Por Anton.
bradvido

Elasticsearch 1.1+ dispune de Agregarea cardinalității care vă va oferi o numărătoare unică

Rețineți că este de fapt o aproximare și că acuratețea poate scădea cu seturi de date cu cardinalitate mare, dar în general este destul de precisă în testele mele.

De asemenea, puteți regla precizia cu ajutorul funcției precision_threshold parametru. Compromisul, desigur, este utilizarea memoriei.

Acest grafic din documentație arată cum o valoare mai mare de precision_threshold duce la rezultate mult mai precise.


Comentarii

  • Agregarea cardinalității garantează că, dacă un termen există, atunci acesta va apărea în rezultate (cu un număr >= 1)? Sau este posibil să rateze unii termeni care apar doar o singură dată într-un set de date mare? –  > Por mark.
  • @mark depinde de pragul de precizie pe care l-ați stabilit. Cu cât pragul este mai mare, cu atât sunt mai puține șanse să rateze. Rețineți că există o limită de 40.000 în ceea ce privește setarea pragului de precizie. Ceea ce înseamnă că, la un set de date mai mare de atât, va exista o estimare și, prin urmare, valoarea unică poate fi ratată –  > Por Sundar.
  • Cred că acest răspuns este greșit. Agregarea cardinalității este un instrument excelent. Cu toate acestea, sarcina a fost de a prelua termenii în sine, nu de a estima câți termeni diferiți există. –  > Por Anton.
MAULIK MODI

Caut acest tip de soluție și pentru mine. Am găsit o referință în agregarea termenilor.

Deci, în conformitate cu aceasta, următoarea este soluția corectă.

{
"aggs" : {
    "langs" : {
        "terms" : { "field" : "language",  
                    "size" : 500 }
    }
}}

Dar dacă ați dat peste următoarea eroare:

"error": {
        "root_cause": [
            {
                "type": "illegal_argument_exception",
                "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [fastest_method] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
            }
        ]}

În acest caz, trebuie să adăugați „KEYWORD” în cerere, după cum urmează:

   {
    "aggs" : {
        "langs" : {
            "terms" : { "field" : "language.keyword",  
                        "size" : 500 }
        }
    }}

MajidJafari

dacă doriți să obțineți primul document pentru fiecare language valoare unică a câmpului, puteți face acest lucru:

{
 "query": {
    "match_all": {
    }
  },
  "collapse": {
    "field": "language.keyword",
    "inner_hits": {
    "name": "latest",
      "size": 1
    }
  }
}

Comentarii

  • „name”: „latest”, este „name” din sintaxa ES sau este un câmp de utilizator personalizat? –  > Por user1769790.
Ilarion Halushka

Dacă doriți să obțineți toate valorile unice fără nicio aproximare sau stabilirea unui număr magic (size: 500), atunci utilizați AGREGARE COMPOZITĂ (ES 6.5+).

De la documentația oficială:

„Dacă doriți să preluați toți termenii sau toate combinațiile de termeni dintr-o agregare de termeni imbricați trebuie să utilizați AGREGAREA COMPUSĂ care permite paginarea tuturor termenilor posibili, mai degrabă decât să setați o dimensiune mai mare decât cardinalitatea câmpului din agregarea de termeni. Agregarea termenilor este menită să returneze termenii de top și nu permite paginarea.”

Exemplu de implementare în JavaScript:

AutoVit

A trebuit să se facă distincție după două câmpuri (derivative_id & vehicle_type) și să se sorteze după cea mai ieftină mașină. Trebuia să se anideze aggs.

GET /cars/_search
{
  "size": 0,
  "aggs": {
    "distinct_by_derivative_id": {
      "terms": { 
        "field": "derivative_id"
      },
      "aggs": {
        "vehicle_type": {
          "terms": {
            "field": "vehicle_type"
          },
          "aggs": {
            "cheapest_vehicle": {
              "top_hits": {
                "sort": [
                  { "rental": { "order": "asc" } }
                ],
                "_source": { "includes": [ "manufacturer_name",
                  "rental",
                  "vehicle_type" 
                  ]
                },
                "size": 1
              }
            }
          }
        }
      }
    }
  }
}

Rezultatul:

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "distinct_by_derivative_id" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "04",
          "doc_count" : 3,
          "vehicle_type" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "CAR",
                "doc_count" : 2,
                "cheapest_vehicle" : {
                  "hits" : {
                    "total" : {
                      "value" : 2,
                      "relation" : "eq"
                    },
                    "max_score" : null,
                    "hits" : [
                      {
                        "_index" : "cars",
                        "_type" : "_doc",
                        "_id" : "8",
                        "_score" : null,
                        "_source" : {
                          "vehicle_type" : "CAR",
                          "manufacturer_name" : "Renault",
                          "rental" : 89.99
                        },
                        "sort" : [
                          89.99
                        ]
                      }
                    ]
                  }
                }
              },
              {
                "key" : "LCV",
                "doc_count" : 1,
                "cheapest_vehicle" : {
                  "hits" : {
                    "total" : {
                      "value" : 1,
                      "relation" : "eq"
                    },
                    "max_score" : null,
                    "hits" : [
                      {
                        "_index" : "cars",
                        "_type" : "_doc",
                        "_id" : "7",
                        "_score" : null,
                        "_source" : {
                          "vehicle_type" : "LCV",
                          "manufacturer_name" : "Ford",
                          "rental" : 99.99
                        },
                        "sort" : [
                          99.99
                        ]
                      }
                    ]
                  }
                }
              }
            ]
          }
        },
        {
          "key" : "01",
          "doc_count" : 2,
          "vehicle_type" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "CAR",
                "doc_count" : 1,
                "cheapest_vehicle" : {
                  "hits" : {
                    "total" : {
                      "value" : 1,
                      "relation" : "eq"
                    },
                    "max_score" : null,
                    "hits" : [
                      {
                        "_index" : "cars",
                        "_type" : "_doc",
                        "_id" : "1",
                        "_score" : null,
                        "_source" : {
                          "vehicle_type" : "CAR",
                          "manufacturer_name" : "Ford",
                          "rental" : 599.99
                        },
                        "sort" : [
                          599.99
                        ]
                      }
                    ]
                  }
                }
              },
              {
                "key" : "LCV",
                "doc_count" : 1,
                "cheapest_vehicle" : {
                  "hits" : {
                    "total" : {
                      "value" : 1,
                      "relation" : "eq"
                    },
                    "max_score" : null,
                    "hits" : [
                      {
                        "_index" : "cars",
                        "_type" : "_doc",
                        "_id" : "2",
                        "_score" : null,
                        "_source" : {
                          "vehicle_type" : "LCV",
                          "manufacturer_name" : "Ford",
                          "rental" : 599.99
                        },
                        "sort" : [
                          599.99
                        ]
                      }
                    ]
                  }
                }
              }
            ]
          }
        },
        {
          "key" : "02",
          "doc_count" : 2,
          "vehicle_type" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "CAR",
                "doc_count" : 2,
                "cheapest_vehicle" : {
                  "hits" : {
                    "total" : {
                      "value" : 2,
                      "relation" : "eq"
                    },
                    "max_score" : null,
                    "hits" : [
                      {
                        "_index" : "cars",
                        "_type" : "_doc",
                        "_id" : "4",
                        "_score" : null,
                        "_source" : {
                          "vehicle_type" : "CAR",
                          "manufacturer_name" : "Audi",
                          "rental" : 499.99
                        },
                        "sort" : [
                          499.99
                        ]
                      }
                    ]
                  }
                }
              }
            ]
          }
        },
        {
          "key" : "03",
          "doc_count" : 1,
          "vehicle_type" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "CAR",
                "doc_count" : 1,
                "cheapest_vehicle" : {
                  "hits" : {
                    "total" : {
                      "value" : 1,
                      "relation" : "eq"
                    },
                    "max_score" : null,
                    "hits" : [
                      {
                        "_index" : "cars",
                        "_type" : "_doc",
                        "_id" : "5",
                        "_score" : null,
                        "_source" : {
                          "vehicle_type" : "CAR",
                          "manufacturer_name" : "Audi",
                          "rental" : 399.99
                        },
                        "sort" : [
                          399.99
                        ]
                      }
                    ]
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}