2015-05-06 8 views
7

_score फ़ील्ड पर या उससे संबंधित समेकन करने के लिए मैंने देखा है (उदाहरण के लिए, ElasticSearch: aggregation on _score field?) प्रत्येक उदाहरण को स्क्रिप्टिंग के उपयोग की आवश्यकता होती है। सुरक्षा कारणों से डिफ़ॉल्ट रूप से डायनामिक स्क्रिप्टिंग को अक्षम करने के साथ, क्या प्रत्येक ईएस नोड पर स्क्रिप्ट फ़ाइल लोड करने या गतिशील स्क्रिप्टिंग को पुन: सक्षम करने के बिना इसे पूरा करने का कोई तरीका है?लोचदार खोज: _score फ़ील्ड w/groovy पर 0 एग्रीग्रेड अक्षम

मेरी मूल एकत्रीकरण निम्नलिखित की तरह लग रहा था:

"aggs": { 
    "terms_agg": { 
     "terms": { 
      "field": "field1", 
      "order": {"max_score": "desc"} 
     }, 
    "aggs": { 
     "max_score": { 
      "max": {"script": "_score"} 
     }, 
     "top_terms": { 
      "top_hits": {"size": 1} 
     } 
     } 
} 

लैंग ES स्कोर बताते हुए एक त्रुटि फेंकता के रूप में काम करने के लिए प्रतीत नहीं होता है के रूप में अभिव्यक्ति निर्दिष्ट करने के लिए कोशिश कर रहा है केवल जब सॉर्ट करने के लिए इस्तेमाल किया जा रहा पहुँचा जा सकता है। मैं स्कोर क्षेत्र द्वारा अपनी बाल्टी को ऑर्डर करने की कोई अन्य विधि नहीं समझ सकता। क्या किसी के भी पास कोई सुझाव है?

संपादित करें: स्पष्ट करने के लिए, मेरा प्रतिबंध सर्वर-पक्ष को संशोधित करने में सक्षम नहीं है। यानी, मैं ईएस स्थापना या कॉन्फ़िगरेशन के हिस्से के रूप में कुछ भी जोड़ या संपादित नहीं कर सकता।

उत्तर

0

एक संभावित तरीका उपलब्ध अन्य स्क्रिप्टिंग विकल्पों का उपयोग करना है। mvel तब तक उपयोग नहीं किया जा सकता जब तक कि गतिशील स्क्रिप्टिंग सक्षम न हो। और, जब तक a more fine-grained control of scripting enable/disable 1.6 संस्करण तक पहुंचता है, मुझे नहीं लगता कि mvel के लिए गतिशील स्क्रिप्टिंग सक्षम करना संभव है और groovy के लिए नहीं।

हम native और mustache (टेम्पलेट्स के लिए उपयोग किए गए) के साथ छोड़ दिए गए हैं जो डिफ़ॉल्ट रूप से सक्षम हैं। मुझे नहीं लगता कि mustache के साथ कस्टम स्क्रिप्टिंग किया जा सकता है, यदि यह संभव है तो मुझे कोई रास्ता नहीं मिला और हमें native (जावा) स्क्रिप्टिंग के साथ छोड़ दिया गया है।

यहाँ इस के लिए मेरे ले रहा है:

  • NativeScriptFactory के एक कार्यान्वयन बनाने के लिए:
package com.foo.script; 

import java.util.Map; 

import org.elasticsearch.script.ExecutableScript; 
import org.elasticsearch.script.NativeScriptFactory; 

public class MyScriptNativeScriptFactory implements NativeScriptFactory { 

    @Override 
    public ExecutableScript newScript(Map<String, Object> arg0) { 
     return new MyScript(); 
    } 

} 
  • उदाहरण के लिए AbstractFloatSearchScript के एक कार्यान्वयन:
package com.foo.script; 

import java.io.IOException; 

import org.elasticsearch.script.AbstractFloatSearchScript; 

public class MyScript extends AbstractFloatSearchScript { 

    @Override 
    public float runAsFloat() { 
     try { 
      return score(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return 0; 
    } 

} 
  • वैकल्पिक रूप से, सभी को एक साथ बांधने के लिए एक सरल Maven परियोजना का निर्माण। pom.xml:
<properties> 
    <elasticsearch.version>1.5.2</elasticsearch.version> 
    <maven.compiler.source>1.8</maven.compiler.source> 
    <maven.compiler.target>1.8</maven.compiler.target> 
</properties> 

<dependencies> 
    <dependency> 
     <groupId>org.elasticsearch</groupId> 
     <artifactId>elasticsearch</artifactId> 
     <version>${elasticsearch.version}</version> 
     <scope>compile</scope> 
    </dependency> 
</dependencies> 

<build> 
    <sourceDirectory>src</sourceDirectory> 
    <plugins> 
     <plugin> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <version>3.1</version> 
      <configuration> 
       <source>1.8</source> 
       <target>1.8</target> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 
  • इसे बनाने और जिसके परिणामस्वरूप जार फ़ाइल मिलता है।
  • जगह [ES_folder]/lib
  • संपादित elasticsearch.yml और script.native.my_script.type: com.foo.script.MyScriptNativeScriptFactory

  • पुनः आरंभ ES नोड्स जोड़ने के अंदर जार।

  • एकत्रित में इसका इस्तेमाल करते हैं:
{ 
    "aggs": { 
    "max_score": { 
     "max": { 
     "script": "my_script", 
     "lang": "native" 
     } 
    } 
    } 
} 

बस ऊपर मेरे नमूना देता है एक स्क्रिप्ट के रूप में _score लेकिन, ज़ाहिर है, यह और अधिक उन्नत स्थितियों में इस्तेमाल किया जा सकता।

संपादित करें: यदि आपको उदाहरणों को छूने की अनुमति नहीं है, तो मुझे नहीं लगता कि आपके पास कोई विकल्प है।

+0

दुर्भाग्य है कि एक आदर्श समाधान नहीं है। इसके अलावा, यह सिर्फ एक ग्रूवी स्क्रिप्ट लिखने और /लिपियों में रखने के लिए काफी आसान हो जाएगा /। उदाहरण के लिए, मेरे मामले में मैं 'एक फ़ाइल बुलाया _score.groovy में _score' लिख सकता है और स्क्रिप्ट में रख/और यह स्वत: ES द्वारा उठाया की जाएगी। मेरे परीक्षण से, मैं भी '{" स्क्रिप्ट ":" _score "} बदलने की जरूरत नहीं होगी' "script_file" का उपयोग करने के लिए कोड है, यह सिर्फ काम करेगा। समस्या यह है कि, इस समाधान के लिए नोड्स को संशोधित करने के लिए सीधी पहुंच की आवश्यकता होती है, जिसे मैं गारंटी नहीं दे सकता। – user4872035

+0

मैंने आपको एक विकल्प दिया, मेरी राय में आपकी राय में केवल एक ही संभव है। आपने कहा कि आप (गतिशील स्क्रिप्टिंग बात की वजह से) ग्रूवी उपयोग करने के लिए और "पर प्रत्येक नोड या फिर से सक्रिय करने के गतिशील स्क्रिप्टिंग ते एक स्क्रिप्ट फ़ाइल को लोड" नहीं करना चाहता नहीं करना चाहती। यदि आप, बजाय, स्क्रिप्ट फ़ाइलों का उपयोग करना चाहते हैं, तो हाँ - आसान, लेकिन आपने कहा कि आप ऐसा नहीं करना चाहते हैं। यदि आप अपने प्रारंभिक प्रतिबंधों को रखते हैं, तो मुझे नहीं लगता कि 'मूल' स्क्रिप्ट से कोई अन्य तरीका है। चीयर्स। –

+0

आह, तो मुझे लगता है कि मेरे प्रतिबंध पर्याप्त स्पष्ट नहीं थे, क्योंकि आपका विकल्प उस बाल्टी में गिरता है (कोई इरादा नहीं है)। मेरा प्रतिबंध एक ईएस क्लस्टर है जिसका मेरा कोई नियंत्रण नहीं है और इसकी कॉन्फ़िगरेशन को संशोधित नहीं किया जा सकता है। मैं स्पष्टीकरण के लिए पोस्ट संपादित करूंगा। धन्यवाद! – user4872035

0

लोचदार खोज कम से कम संस्करण 1.7.1 और संभवतः पहले ल्यूसीन की अभिव्यक्ति स्क्रिप्टिंग भाषा का उपयोग भी प्रदान करता है - और अभिव्यक्ति डिफ़ॉल्ट रूप से सैंडबॉक्स किया जाता है, इसलिए इसे गतिशील इनलाइन स्क्रिप्ट के लिए भी इस्तेमाल किया जा सकता है जैसा कि ग्रोवी था। हमारे मामले में, जहां हमारे उत्पादन ईएस क्लस्टर को अभी 1.4.1 से 1.7.1 तक अपग्रेड किया गया है, हमने निर्णय लिया है कि अब इसकी गैर-सैंडबॉक्स वाली प्रकृति की वजह से ग्रोवी का उपयोग न करें, हालांकि हम वास्तव में अभी भी गतिशील स्क्रिप्ट का उपयोग करना चाहते हैं तैनाती की आसानी और उनके द्वारा प्रदान की जाने वाली लचीलापन के रूप में हम अपने आवेदन और इसकी खोज परत को सुदृढ़ करना जारी रखते हैं।

हमारे गतिशील ग्रोवी फ़ंक्शन स्कोर के प्रतिस्थापन के रूप में मूल जावा स्क्रिप्ट लिखते समय हमारे मामले में भी संभावना हो सकती है, हम इसके बजाय हमारी गतिशील इनलाइन स्क्रिप्टिंग भाषा के लिए अभिव्यक्ति का उपयोग करने की व्यवहार्यता को देखना चाहते थे। प्रलेखन के माध्यम से पढ़ने के बाद, मैंने पाया कि हम "groovy" से "expression" से हमारी इनलाइन function_score स्क्रिप्ट में "लैंग" विशेषता को बदलने में सक्षम थे और .../config/elasticsearch.yml फ़ाइल में प्रॉपर्टी सेट के साथ - फ़ंक्शन स्कोर स्क्रिप्ट किसी भी अन्य संशोधन के बिना काम करती थी। इस प्रकार, हम अब ElasticSearch के भीतर गतिशील इनलाइन स्क्रिप्टिंग का उपयोग करना जारी रख सकते हैं, और सैंडबॉक्सिंग सक्षम के साथ ऐसा करते हैं (क्योंकि अभिव्यक्ति डिफ़ॉल्ट रूप से सैंडबॉक्स है)। स्पष्ट रूप से अन्य सुरक्षा उपायों जैसे कि एप्लिकेशन प्रॉक्सी और फ़ायरवॉल के पीछे अपना ईएस क्लस्टर चलाने के लिए भी लागू किया जाना चाहिए ताकि बाहरी उपयोगकर्ताओं को आपके ईएस नोड्स या ईएस एपीआई तक सीधे पहुंच न हो। हालांकि, यह एक बहुत ही सरल परिवर्तन था, क्योंकि अब ग्रोवी की सैंडबॉक्सिंग की कमी और सैंडबॉक्सिंग के बिना इसे चलाने में सक्षम होने के कारण समस्याएं हल हुई हैं।

अभिव्यक्ति में अपनी गतिशील स्क्रिप्ट को स्विच करते समय केवल कुछ मामलों में काम कर सकते हैं या लागू हो सकते हैं (आपकी इनलाइन गतिशील स्क्रिप्ट की जटिलता के आधार पर), ऐसा लगता है कि यह जानकारी अन्य उम्मीदवारों की मदद से उम्मीद कर सकती है।

एक नोट के रूप में, अन्य समर्थित ईएस स्क्रिप्टिंग भाषाओं में से एक, मूंछ केवल आपके खोज प्रश्नों के भीतर टेम्पलेट बनाने के लिए प्रयोग योग्य प्रतीत होता है। यह function_score इत्यादि जैसी किसी भी जटिल स्क्रिप्टिंग आवश्यकताओं के लिए उपयोग करने योग्य प्रतीत नहीं होता है, हालांकि मुझे यकीन नहीं है कि अद्यतन ईएस दस्तावेज़ीकरण के माध्यम से पहले पढ़ने के दौरान यह पूरी तरह से स्पष्ट था।

अन्त में, एक और मुद्दा के प्रति जागरूक होने के लिए कि Lucene अभिव्यक्ति लिपियों का उपयोग एक प्रायोगिक सुविधा के रूप में चिह्नित कर रहे हैं नवीनतम ES रिलीज में है और प्रलेखन लिखते हैं कि इस पटकथा विस्तार के रूप में इस पर काफी विकास कार्य किया जा रहा है समय, इसका उपयोग या कार्यक्षमता ईएस के बाद के संस्करणों में बदल सकती है। इस प्रकार यदि आप अपनी किसी भी स्क्रिप्ट (गतिशील या अन्यथा) के लिए अभिव्यक्ति का उपयोग करने के लिए स्विच करते हैं, तो अगली बार अपनी ईएस स्थापना को अपग्रेड करने से पहले इन परिवर्तनों पर फिर से विचार करने के लिए अपने दस्तावेज़/डेवलपर नोट्स में ध्यान दिया जाना चाहिए ताकि आपकी स्क्रिप्ट सुसंगत रहें और काम करें अपेक्षित होना।

कम से कम हमारी स्थिति के लिए, जब तक हम ईएस के नवीनतम संस्करण (script.inline: on विकल्प के माध्यम से) फिर से गैर-सैंडबॉक्स वाली गतिशील स्क्रिप्टिंग को सक्षम करने की अनुमति नहीं दे रहे थे, ताकि इनलाइन ग्रोवी स्क्रिप्ट चलाना जारी रख सकें, स्विच कर सकें लुसीन अभिव्यक्ति स्क्रिप्टिंग अब के लिए सबसे अच्छा विकल्प की तरह लग रहा था।

यह देखना दिलचस्प होगा कि भविष्य में रिलीज में ईएस के लिए स्क्रिप्टिंग विकल्पों में क्या परिवर्तन होते हैं, विशेष रूप से यह देखते हुए कि ग्रोवी के लिए (स्पष्ट रूप से अप्रभावी) सैंडबॉक्सिंग विकल्प पूरी तरह से संस्करण 2.0 द्वारा हटा दिया जाएगा। उम्मीद है कि अन्य सुरक्षा जगह में रखा जा सकता है गतिशील ग्रूवी उपयोग, या शायद Lucene अभिव्यक्ति पटकथा सक्षम करने के लिए ग्रूवी की जगह ले जाएगा और गतिशील स्क्रिप्टिंग के सभी प्रकार कि डेवलपर्स पहले से ही के उपयोग कर रहे हैं सक्षम हो जाएगा।

लुसीन अभिव्यक्ति पर अधिक नोट्स के लिए यहां ईएस दस्तावेज देखें: https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html#_lucene_expressions_scripts - यह पृष्ठ ईएस v2.0 + से ग्रोवी के सैंडबॉक्सिंग विकल्प के नियोजित हटाने के संबंध में नोट का स्रोत भी है। इसके अलावा Lucene अभिव्यक्ति प्रलेखन यहां पाया जा सकता: http://lucene.apache.org/core/4_9_0/expressions/index.html?org/apache/lucene/expressions/js/package-summary.html

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