ElasticSearch - अद्वितीय मान लौटाएँ


122

मुझे सभी का मान कैसे मिलेगा languages रिकॉर्ड्स से और उन्हें अद्वितीय बनाऊंगा।

अभिलेख

PUT items/1
{ "language" : 10 }

PUT items/2
{ "language" : 11 }

PUT items/3
{ "language" : 10 }

सवाल

GET items/_search
{ ... }

# => Expected Response
[10, 11]

कोई भी मदद बहुत अच्छी रहेगी।


1
fields: [languages]दिए गए फ़ील्ड के केवल मान देगा, लेकिन उन्हें अद्वितीय बनाना शायद कोड में करना आसान है। हालांकि एक आसान एकत्रीकरण हो सकता है जो आपके लिए कर सकता है।
आशालैंड

1
इस विषय पर शोध करने वालों के लिए, यहां भी उपयोगी चर्चा है: अलग-अलग मूल्य खोजें,
इलास्टिक्स खोज

जवाबों:


165

आप शब्दों के एकत्रीकरण का उपयोग कर सकते हैं ।

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

एक खोज कुछ इस तरह लौटेगी:

{
"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
       } ]
    }
  }
}

sizeएकत्रीकरण के भीतर का पैरामीटर एकत्रीकरण परिणाम में शामिल करने के लिए अधिकतम संख्या निर्दिष्ट करता है। यदि आपको सभी परिणामों की आवश्यकता है, तो इसे ऐसे मान पर सेट करें जो आपके डेटा की अद्वितीय शर्तों की संख्या से बड़ा हो।


2
"fields" : ["language"]उसी परिणाम को वापस लाता है। क्या आप यह देखने के लिए अपने जवाब पर विस्तार कर सकते हैं कि क्या एकत्रीकरण ढांचा सिर्फ भाषा मूल्यों पर लौट सकता है? #=> [10, 11, 10]
चुक्जहार्डी

1
@CharlesJHardy, इसका एक ही परिणाम नहीं है। आप जो डेटा देख रहे हैं, वह "एकत्रीकरण" कुंजी के तहत है। मैंने अपना उत्तर एक उदाहरण परिणाम के साथ संपादित किया। आप "आकार" भी निर्धारित कर सकते हैं: 0, किसी भी दस्तावेज को शामिल नहीं करने के लिए, केवल आपके द्वारा वांछित परिणाम।
एंटोन

1
ध्यान दें कि यदि आपके पास कई संभावित मूल्य हैं, languageतो आप जोड़ना चाहते हैं size=0और shard_size=0, यह सुनिश्चित करने के लिए कि आपको सभी मूल्य मिलेंगे । Elasticsearch.org/guide/en/elasticsearch/reference/current/…
Dr

3
मुझे लगता है कि यह जवाब ओपी को संबोधित नहीं करता है। मूल प्रश्न अलग-अलग मूल्यों को गिनना नहीं चाहता है । क्या मैं कुछ भूल रहा हूँ?
भूरलो

4
@BHBH, उत्तर अलग-अलग मान प्रदान करता है। वे "प्रमुख" मूल्य हैं, अर्थात, "10", "11" और "12"। (एकत्रीकरण> लंग्स> बाल्टी> कुंजी ...)
एंटोन

9

इलास्टिसर्च 1.1+ में कार्डिनैलिटी एग्रीगेशन है जो आपको एक अद्वितीय गिनती देगा

ध्यान दें कि यह वास्तव में एक अनुमान है और उच्च-हृदयता वाले डेटासेट के साथ सटीकता कम हो सकती है, लेकिन यह आम तौर पर मेरे परीक्षण में बहुत सटीक है।

आप precision_thresholdपैरामीटर के साथ सटीकता को भी ट्यून कर सकते हैं । व्यापार बंद, या पाठ्यक्रम, स्मृति उपयोग है।

डॉक्स के इस ग्राफ से पता चलता है कि एक उच्च कैसे precision_thresholdअधिक सटीक परिणामों की ओर ले जाता है।


सापेक्ष त्रुटि बनाम सीमा


2
क्या कार्डिनैलिटी एग्रीगेशन की गारंटी है कि यदि कोई शब्द मौजूद है, तो यह परिणामों में दिखाई देगा (एक गिनती के साथ = = 1)? या यह संभवतः कुछ शब्दों को याद कर सकता है जो केवल एक बार बड़े डेटासेट में दिखाई देते हैं?
चिह्नित करें

2
@ यह आपके द्वारा निर्धारित सटीक सीमा पर निर्भर करता है। यह सीमा जितनी अधिक होगी, उतना ही कम मौका मिलेगा। ध्यान दें कि सटीक थ्रेसहोल्ड सेटिंग में 40,000 की सीमा है। जिसका अर्थ है, एक डेटा तुलना में अधिक निर्धारित करते हैं, एक अनुमान है और इसलिए एकल मान याद किया जा सकता है नहीं होगा
सुंदर

12
मेरा मानना ​​है कि यह उत्तर गलत है। कार्डिनैलिटी एकत्रीकरण एक उत्कृष्ट उपकरण है। हालाँकि, कार्य स्वयं शर्तों को प्राप्त करना था, न कि कितने अलग-अलग शब्द हैं, इसका अनुमान लगाना।
एंटोन

4

यदि आप प्रत्येक languageफ़ील्ड के लिए पहला दस्तावेज़ प्राप्त करना चाहते हैं , तो आप ऐसा कर सकते हैं:

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

3

मैं अपने स्वयं के लिए भी इस तरह के समाधान की तलाश कर रहा हूं। मुझे संदर्भ एकत्रीकरण में संदर्भ मिला ।

तो, उसके अनुसार निम्नलिखित उचित समाधान है।

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

लेकिन अगर आप निम्नलिखित त्रुटि में भाग गए:

"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."
            }
        ]}

उस स्थिति में, आपको अनुरोध में " KEYWORD " जोड़ना होगा , जैसे निम्नलिखित:

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

1

यदि आप बिना किसी सन्निकटन या मैजिक नंबर ( size: 500) के सभी विशिष्ट मान प्राप्त करना चाहते हैं , तो COMPOSITE AGGREGATION (ES 6.5+) का उपयोग करें

से आधिकारिक दस्तावेज :

"यदि आप एक नेस्टेड शब्द एकत्रीकरण में सभी शर्तों या सभी संयोजनों को फिर से प्राप्त करना चाहते हैं, तो आपको COMPOSITE AGGREGATION का उपयोग करना चाहिए जो शर्तों के एकत्रीकरण में क्षेत्र की कार्डिनैलिटी से अधिक एक आकार सेट करने के बजाय सभी संभावित शर्तों पर पृष्ठांकित करने की अनुमति देता है।" शब्द एकत्रीकरण का मतलब शीर्ष शर्तों को वापस करना है और अंकुरण की अनुमति नहीं देता है। "

जावास्क्रिप्ट में कार्यान्वयन उदाहरण:

const ITEMS_PER_PAGE = 1000;

const body =  {
    "size": 0, // Returning only aggregation results: https://www.elastic.co/guide/en/elasticsearch/reference/current/returning-only-agg-results.html
    "aggs" : {
        "langs": {
            "composite" : {
                "size": ITEMS_PER_PAGE,
                "sources" : [
                    { "language": { "terms" : { "field": "language" } } }
                ]
            }
        }
     }
};

const uniqueLanguages = [];

while (true) {
  const result = await es.search(body);

  const currentUniqueLangs = result.aggregations.langs.buckets.map(bucket => bucket.key);

  uniqueLanguages.push(...currentUniqueLangs);

  const after = result.aggregations.langs.after_key;

  if (after) {
      // continue paginating unique items
      body.aggs.langs.composite.after = after;
  } else {
      break;
  }
}

console.log(uniqueLanguages);

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.