2015-06-09 13 views
32

मैं वर्तमान में देखे जाने वाले संबंधित टैग को ढूंढने का प्रयास कर रहा हूं। हमारे सूचकांक में प्रत्येक दस्तावेज़ टैग किया गया है। प्रत्येक टैग दो भागों से ही बना है - एक आईडी और पाठ का नाम:एकाधिक फ़ील्ड के साथ लोचदार खोज एकत्रीकरण कैसे प्राप्त करें

{ 
    "query": { 
     "bool": { 
      "must": [ 
       { 
        "match": { 
         "item.meta.tags.id": "123" 
        } 
       }, 
       { 
        ... 
       } 
      ] 
     } 
    }, 
    "aggs": { 
     "baked_goods": { 
      "terms": { 
       "field": "item.meta.tags.id", 
       "min_doc_count": 2 
      } 
     } 
    } 
} 

यह पूरी तरह से काम करता है:

{ 
    ... 
    meta: { 
     ... 
     tags: [ 
      { 
       id: 123, 
       name: 'Biscuits' 
      }, 
      { 
       id: 456, 
       name: 'Cakes' 
      }, 
      { 
       id: 789, 
       name: 'Breads' 
      } 
     ] 
    } 
} 

संबंधित टैग मैं बस दस्तावेजों की क्वेरी कर रहा हूँ और उनके टैग के एक समग्र हो रही लाने के लिए , मुझे वह परिणाम मिल रहा है जो मैं चाहता हूं। हालांकि, मुझे कुछ भी उपयोगी करने के लिए टैग आईडी और नाम दोनों की आवश्यकता है। मैं यह कैसे पूरा करने के लिए पता लगाया है, समाधान होने लगते हैं:

  1. क्षेत्रों कम्बाइन जब
  2. एक स्क्रिप्ट का अनुक्रमण क्षेत्रों को एक साथ Munge को
  3. एक नेस्टेड एकत्रीकरण

विकल्प एक और दो मेरे लिए उपलब्ध नहीं हैं इसलिए मैं 3 के साथ जा रहा हूं लेकिन यह अपेक्षित तरीके से प्रतिक्रिया नहीं दे रहा है। निम्न क्वेरी को देखते हुए (अब भी दस्तावेजों को भी 'बिस्कुट' के साथ टैग के लिए खोज):

{ 
    ... 
    "aggregations": { 
     "baked_goods": { 
      "buckets": [ 
       { 
        "key": "456", 
        "doc_count": 11, 
        "name": { 
         "buckets": [ 
          { 
           "key": "Biscuits", 
           "doc_count": 11 
          }, 
          { 
           "key": "Cakes", 
           "doc_count": 11 
          } 
         ] 
        } 
       } 
      ] 
     } 
    } 
} 

नेस्टेड एकत्रीकरण दोनों खोज पद और टैग में शामिल हैं:

{ 
    ... 
    "aggs": { 
     "baked_goods": { 
      "terms": { 
       "field": "item.meta.tags.id", 
       "min_doc_count": 2 
      }, 
      "aggs": { 
       "name": { 
        "terms": { 
         "field": "item.meta.tags.name" 
        } 
       } 
      } 
     } 
    } 
} 

मैं इस परिणाम मिल जाएगा मैं बाद में (वर्णानुक्रम में लौटा)।

मैंने नेस्टेड एग्रीगेशन में exclude जोड़ कर इसे कम करने की कोशिश की है, लेकिन इसने क्वेरी को बहुत अधिक धीमा कर दिया (500000 दस्तावेज़ों के लिए लगभग 100 बार)। अब तक का सबसे तेज़ समाधान परिणाम को मैन्युअल रूप से डी-डुप्लिकेट करना है।

प्रतिक्रिया में टैग आईडी और टैग नाम दोनों के साथ टैग एकत्र करने का सबसे अच्छा तरीका क्या है?

इसे अभी तक बनाने के लिए धन्यवाद!

उत्तर

44

इसे देखकर, आपके tagsnested नहीं है। काम करने के लिए इस एकत्रीकरण के लिए, you need it nested ताकि id और name के बीच कोई संबंध हो। nested बिना id रों की सूची सिर्फ एक सरणी और name रों की सूची इस प्रकार है एक और सरणी है:

"item": { 
     "properties": { 
     "meta": { 
      "properties": { 
      "tags": { 
       "type": "nested",   <-- nested field 
       "include_in_parent": true, <-- to, also, keep the flat array-like structure 
       "properties": { 
       "id": { 
        "type": "integer" 
       }, 
       "name": { 
        "type": "string" 
       } 
       } 
      } 
      } 
     } 
     } 
    } 

इसके अलावा, ध्यान दें कि मैं मानचित्रण में शामिल किया है इस लाइन "include_in_parent": true जिसका अर्थ है कि आपके nested टैग होगा, भी, एक "फ्लैट" सरणी जैसी संरचना की तरह व्यवहार करते हैं।

तो, आपके प्रश्नों में अब तक जो कुछ भी था, वह अभी भी प्रश्नों में किए गए किसी भी बदलाव के बिना काम करेगा।

लेकिन, आपके इस विशेष क्वेरी के लिए, एकत्रीकरण कुछ इस तरह करने के लिए बदलने की जरूरत:

{ 
    "aggs": { 
    "baked_goods": { 
     "nested": { 
     "path": "item.meta.tags" 
     }, 
     "aggs": { 
     "name": { 
      "terms": { 
      "field": "item.meta.tags.id" 
      }, 
      "aggs": { 
      "name": { 
       "terms": { 
       "field": "item.meta.tags.name" 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

और परिणाम इस तरह है:

"aggregations": { 
     "baked_goods": { 
     "doc_count": 9, 
     "name": { 
      "doc_count_error_upper_bound": 0, 
      "sum_other_doc_count": 0, 
      "buckets": [ 
       { 
        "key": 123, 
        "doc_count": 3, 
        "name": { 
        "doc_count_error_upper_bound": 0, 
        "sum_other_doc_count": 0, 
        "buckets": [ 
         { 
          "key": "biscuits", 
          "doc_count": 3 
         } 
        ] 
        } 
       }, 
       { 
        "key": 456, 
        "doc_count": 2, 
        "name": { 
        "doc_count_error_upper_bound": 0, 
        "sum_other_doc_count": 0, 
        "buckets": [ 
         { 
          "key": "cakes", 
          "doc_count": 2 
         } 
        ] 
        } 
       }, 
       ..... 
+1

@i_like_robots मैं उत्सुक हूँ, क्या आपने मेरे सुझाए गए समाधान का परीक्षण किया है? –

+1

उसने खुद के लिए बक्षीस रखने का फैसला किया, अच्छे जवाब के लिए धन्यवाद! – asktomsk

+2

अंत में, हाँ! हम अंततः सही ढंग से घोंसले वाले खेतों के साथ एक नई अनुक्रमणिका बनाने में समय बिताने में सक्षम थे लेकिन मुझे डर है कि यह हाल ही में तब तक नहीं था। मेरे प्रश्न का उत्तर देने के लिए धन्यवाद और मैं किसी भी स्टैक ओवरफ्लो शिष्टाचार की उपेक्षा करने के लिए क्षमा चाहता हूं! –

संबंधित मुद्दे