2012-10-01 15 views
17

का उपयोग कर सरणी ऑब्जेक्ट प्रकार में सटीक खोज मैं सटीक लोचदार खोज में सरणी मिलान करने का एक तरीका ढूंढ रहा हूं। की ये मेरे दस्तावेज हैं मान लीजिए:elasticsearch

{"id": 1, "categories" : ["c", "d"]} 
{"id": 2, "categories" : ["b", "c", "d"]} 
{"id": 3, "categories" : ["c", "d", "e"]} 
{"id": 4, "categories" : ["d"]} 
{"id": 5, "categories" : ["c", "d"]} 

वहाँ के लिए खोज करने के लिए एक रास्ता है सभी दस्तावेज़ की है कि राशि बिल्कुल श्रेणियों "सी" और "डी" (दस्तावेजों 1 और 5), कोई और अधिक या कम?

एक बोनस के रूप: के लिए श्रेणियों "इनमें से एक" अभी भी रूप में अच्छी तरह संभव हो जाना चाहिए (उदाहरण के लिए आप "सी" के लिए खोज सकते हैं और 1, 2, 3 हो और 5)

किसी भी चालाक रास्ता के लिए सर्च कर रहे हैं इस समस्या से निपटें?

"bool" : { 
    "must" : { 
     "terms" : { "categories" : ["c", "d"], 
      minimum_should_match : 2 
     } 
    }, 
    "must_not" : { 
     "terms" : { "categories" : ["a", "b", "e"], 
      minimum_should_match : 1 
     } 
    } 
} 

अन्यथा शायद सबसे आसान तरीका है यह पूरा करने,, मुझे लगता है, है एक और क्षेत्र एक के रूप में सेवारत स्टोर करने के लिए:

उत्तर

19

आप श्रेणियों की एक असतत, जाना जाता है सेट है, तो आप एक bool क्वेरी इस्तेमाल कर सकते हैं श्रेणियों का कीवर्ड।

{"id": 1, "categories" : ["c", "d"], "categorieskey" : "cd"} 

ऐसा कुछ। फिर आप अपने इच्छित परिणामों के लिए आसानी से एक शब्द क्वेरी के साथ पूछ सकते हैं, जैसे:

term { "categorieskey" : "cd" } 

और आप अभी भी गैर-विशेष रूप से खोज सकते हैं;

term { "categories" : "c" } 

दो श्रेणियों कि दोनों मौजूद होना चाहिए के लिए पता कर रहा है बहुत आसान है, लेकिन फिर मौजूद होने से किसी भी अन्य संभावित श्रेणियों को रोकने थोड़ा मुश्किल है। आप शायद यह कर सकते हैं। आप शायद दोनों के साथ रिकॉर्ड खोजने के लिए एक प्रश्न लिखना चाहते हैं, फिर निर्दिष्ट फ़िल्टर के अलावा श्रेणियों के साथ किसी भी रिकॉर्ड को समाप्त करने के लिए एक फ़िल्टर लागू करें। यह वास्तव में एक तरह की खोज नहीं है कि लुसीन वास्तव में मेरे ज्ञान को संभालने के लिए डिज़ाइन किया गया है।

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

+1

मजाकिया, कि वास्तव में मैं उसे क्या बताया था :) – phoet

+0

@phoet तुम इतने स्मार्ट;) – paukul

+0

@femtoRgon धन्यवाद! दुर्भाग्य से यह बुरी खबर है :) – paukul

1

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

{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "match": { 
      "siteId": 4 
      } 
     }, 
     { 
      "match": { 
      "marketBasketList": { 
       "query": [ 
       10, 
       11 
       ], 
       "operator": "and" 
      } 
      } 
     } 
     ] 
    }, 
    "boost": 1, 
    "filter": { 
     "and": { 
     "filters": [ 
      { 
      "script": { 
       "script": "doc['marketBasketList'].values.length == 2" 
      } 
      }, 
      { 
      "terms": { 
       "marketBasketList": [ 
       10, 
       11 
       ], 
       "execution": "and" 
      } 
      } 
     ] 
     } 
    } 
    } 
}