2012-03-20 17 views
24

this issue वैकल्पिक बीज के साथ यादृच्छिक क्रम के मनोरंजन के लिए अनुमति देने के लिए एक सुविधा अनुरोध है।यादृच्छिक क्रम और अंकन Elasticsearch

मुझे यादृच्छिक आदेशित परिणामों को पेजगेट करने में सक्षम होना चाहिए। यह Elasticsearch 0.19.1 के साथ कैसे किया जा सकता है?

धन्यवाद।

उत्तर

30

आप एक अद्वितीय क्षेत्र (उदाहरण आईडी के लिए) और एक यादृच्छिक नमक के हैश फ़ंक्शन का उपयोग करके सॉर्ट कर सकते हैं। कैसे सही मायने में यादृच्छिक परिणाम होना चाहिए के आधार पर आप के रूप में के रूप में आदिम कुछ कर सकते हैं:

{ 
    "query" : { "query_string" : {"query" : "*:*"} }, 
    "sort" : { 
    "_script" : { 
     "script" : "(doc['_id'].value + salt).hashCode()", 
     "type" : "number", 
     "params" : { 
      "salt" : "some_random_string" 
     }, 
     "order" : "asc" 
    } 
    } 
} 

या के रूप में

{ 
    "query" : { "query_string" : {"query" : "*:*"} }, 
    "sort" : { 
    "_script" : { 
     "script" : "org.elasticsearch.common.Digest.md5Hex(doc['_id'].value + salt)", 
     "type" : "string", 
     "params" : { 
      "salt" : "some_random_string" 
     }, 
     "order" : "asc" 
    } 
    } 
} 

दूसरे उदाहरण अधिक यादृच्छिक परिणाम देगा लेकिन कुछ हद तक धीमी हो जाएगा के रूप में परिष्कृत कुछ ।

फ़ील्ड _id को संग्रहीत करने के लिए इस दृष्टिकोण के लिए संग्रहीत किया जाना है। अन्यथा, क्वेरी NullPointerException के साथ विफल हो जाएगी।

+0

क्या मैं क्लाइंट पर स्ट्रिंग को स्टोर करूंगा? उदाहरण के लिए एक कुकी में? ताकि जब उपयोगकर्ता पृष्ठ 2 के लिए कॉल करता है तो वही आदेश संरक्षित होता है? – Yeggeps

+0

नमक स्ट्रिंग को उत्पन्न किया जाना चाहिए और उस परत पर संग्रहीत किया जाना चाहिए जो उपयोगकर्ता के सत्र को बनाए रखता है। यह वही स्थान हो सकता है जहां आप उपयोगकर्ता की क्वेरी या वर्तमान में प्रदर्शित पृष्ठ संख्या संग्रहीत करते हैं। यह कुकी भी हो सकता है। – imotov

3

मैंने इसे इमोटोव सुझाव के मुकाबले थोड़ा अलग हल कर दिया। चूंकि मेरे पास कई क्लाइंट हैं, इसलिए मैं उनमें से प्रत्येक पर नमक स्ट्रिंग के आस-पास तर्क को लागू नहीं करना चाहता था।

मेरे पास मॉडल पर पहले से ही यादृच्छिक_की थी। मुझे हर अनुरोध के लिए यादृच्छिक होने के आदेश की भी आवश्यकता नहीं थी इसलिए मैंने प्रत्येक रात यादृच्छिक कुंजी को अद्यतन करने के लिए एक निर्धारित कार्य किया और फिर उस क्षेत्र द्वारा Elasticssearch में क्रमबद्ध किया गया।

18

imotov से अच्छा समाधान।

यहाँ

है कुछ और अधिक सरल और आप एक दस्तावेज़ संपत्ति में भरोसा करने की जरूरत नहीं है:

{ 
    "query" : { "query_string" : {"query" : "*:*"} }, 
    "sort" : { 
    "_script" : { 
     "script" : "Math.random()", 
     "type" : "number", 
     "params" : {}, 
     "order" : "asc" 
    } 
    } 
} 

आप एक सीमा है कि हो सकता है सेट करना चाहते हैं कुछ की तरह:

{ 
    "query" : { "query_string" : {"query" : "*:*"} }, 
    "sort" : { 
    "_script" : { 
     "script" : "Math.random() * (myMax - myMin) + myMin", 
     "type" : "number", 
     "params" : {}, 
     "order" : "asc" 
    } 
    } 
} 

अधिकतम और न्यूनतम को अपने उचित मूल्यों से बदलना।

+5

यह एक अच्छा सामान्य समाधान है। हालांकि, मूल प्रश्न "वैकल्पिक बीज को यादृच्छिक क्रम के मनोरंजन के लिए अनुमति देने" के लिए पूछ रहा था। यही वह जगह है जहां से सभी जटिलताएं आ रही हैं। – imotov

+0

हां, आप पूरी तरह से सही हैं। मेरा समाधान "यादृच्छिक क्रम और अंकन Elasticsearch" शीर्षक के लिए अधिक उपयुक्त है। Yeggeps जरूरतों के लिए पूरी तरह से अपर्याप्त। – DavidGOrtega

+3

मूल यादृच्छिक क्रम के लिए उत्कृष्ट उत्तर, धन्यवाद – Eva

50

यह और ऊपर दोनों उत्तर की तुलना में काफी तेजी से किया जाना चाहिए समर्थन करता है, बोने:

curl -XGET 'localhost:9200/_search' -d '{ 
    "query": { 
    "function_score" : { 
     "query" : { "match_all": {} }, 
     "random_score" : {} 
    } 
    } 
}'; 

देखें: https://github.com/elasticsearch/elasticsearch/issues/1170

+1

आपकी मदद के लिए धन्यवाद। मुझे लगता है कि उत्तर अधिक स्पष्ट कर देगा कि अगर आप उदाहरण क्वेरी अपडेट करते हैं तो random_score बीजिंग का समर्थन करता है। –

+0

यदि आप फ़िल्टर का उपयोग करते हैं तो काम नहीं करता है। –

0

ठीक है, मैं यह कर देख रहा था और सभी दृष्टिकोण से ऊपर एक छोटे से "बहुत जटिल लग रहा था "कुछ ऐसा जो अपेक्षाकृत सरल होना चाहिए। तो मैं एक विकल्प है कि पूरी तरह से "मानसिक जा रहा"

मैं पहली बार एक _count क्वेरी निष्पादित तो "प्रारंभ" और रैंड (0, $ गिनती)

उदा के साथ संयोजित की आवश्यकता के बिना अच्छी तरह से काम के साथ आया थाऊपर के उदाहरण के लिए

JSONArray = array of json to send to ElasticSearch 
$total_results = $ElasticSearchClient->count(JSONArray) 
$start = rand(0, $total_results) 
JSONArray['body']['from'] = $start; 
$ElasticSearchClient->search(JSONArray); 

अनुमान:

  • आप चला रहे हैं पीएचपी
  • तुम भी पीएचपी ग्राहक

उपयोग कर रहे हैं लेकिन आप न के साथ ऐसा करने की जरूरत है PHP, दृष्टिकोण किसी भी उदाहरण के साथ काम करेगा।