2013-12-17 10 views
28

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

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

धन्यवाद।

मानचित्रण

{ 
    "jr": { 
    "_all": { 
     "enabled": true, 
     "index_analyzer": "index_analyzer", 
     "search_analyzer": "search_analyzer" 
    }, 
    "properties": { 
     "pty_forename": { 
      "type": "string", 
      "index": "analyzed", 
      "boost": 2, 
      "index_analyzer": "index_analyzer", 
      "search_analyzer": "search_analyzer", 
      "store": "yes" 
     }, 
     "pty_full_name": { 
      "type": "string", 
      "index": "analyzed", 
      "boost": 4, 
      "index_analyzer": "index_analyzer", 
      "search_analyzer": "search_analyzer", 
      "store": "yes" 
     }, 
     "pty_surname": { 
      "type": "string", 
      "index": "analyzed", 
      "boost": 4, 
      "index_analyzer": "index_analyzer", 
      "search_analyzer": "search_analyzer", 
      "store": "yes" 
     } 
    } 
    } 
}' 

सूचकांक सेटिंग्स

{ 
    "settings": { 
    "number_of_shards": 2, 
    "number_of_replicas": 0, 
    "analysis": { 
     "analyzer": { 
      "index_analyzer": { 
       "tokenizer": "standard", 
       "filter": [ 
        "standard", 
        "my_delimiter", 
        "lowercase", 
        "stop", 
        "asciifolding", 
        "porter_stem", 
        "my_metaphone" 
       ] 
      }, 
      "search_analyzer": { 
       "tokenizer": "standard", 
       "filter": [ 
        "standard", 
        "my_metaphone", 
        "synonym", 
        "lowercase", 
        "stop", 
        "asciifolding", 
        "porter_stem" 
       ] 
      } 
     }, 
     "filter": { 
      "synonym": { 
       "type": "synonym", 
       "synonyms_path": "synonyms/synonyms.txt" 
      }, 
      "my_delimiter": { 
       "type": "word_delimiter", 
       "generate_word_parts": true, 
       "catenate_words": false, 
       "catenate_numbers": false, 
       "catenate_all": false, 
       "split_on_case_change": false, 
       "preserve_original": false, 
       "split_on_numerics": false, 
       "stem_english_possessive": false 
      }, 
      "my_metaphone": { 
       "type": "phonetic", 
       "encoder": "metaphone", 
       "replace": false 
      } 
     } 
    } 
    } 
}' 

फजी

{ 
"from":0, "size":100, 
"query": { 
    "bool": { 
     "should": [ 
      { 
       "fuzzy": { 
        "pty_surname": { 
         "min_similarity": 0.2, 
         "value": "Heaney", 
         "prefix_length": 0, 
         "boost": 5 
        } 
       } 
      }, 
      { 
       "fuzzy": { 
        "pty_forename": { 
         "min_similarity": 1, 
         "value": "Michael", 
         "prefix_length": 0, 
         "boost": 1 
        } 
       } 
      } 
     ] 
    } 
    } 
} 

उत्तर

28

पहले, मैं निर्मित अपने https://www.found.no/play/gist/867785a709b4869c5543

तुम वहाँ जाते हैं, "विश्लेषण" -tab को देखना चाहते हैं कि पाठ तब्दील हो जाता है स्विच: प्ले में वर्तमान कॉन्फ़िगरेशन

ध्यान दें, [hn, heanei] रूप search_analyzer साथ उदाहरण के लिए कि Heaney tokenized समाप्त होता है और index_analyzer के साथ। मेटाफोन-टर्म के लिए केस-फ़र्क नोट करें। इस प्रकार, वह मेल नहीं खाता है।

fuzzy -query क्वेरी समय टेक्स्ट विश्लेषण नहीं करता है। इस प्रकार, आप Heavey की तुलना heanei के साथ तुलना करते हैं। आपके पैरामीटर की अनुमति के मुकाबले इसमें Damerau-Levenshtein distance लंबा है।

आप वास्तव में क्या करना चाहते हैं match की अस्पष्ट कार्यक्षमता का उपयोग कर रहा है। मैच क्वेरी समय टेक्स्ट विश्लेषण करते हैं, और फ़ज़ीनेस -parameter है।

fuzziness के लिए, यह लुसीन 4 में थोड़ा सा बदल गया। इससे पहले, इसे आम तौर पर एक फ्लोट के रूप में निर्दिष्ट किया गया था। अब इसे अनुमत दूरी के रूप में निर्दिष्ट किया जाना चाहिए। यह स्पष्ट करने के लिए एक उत्कृष्ट पुल अनुरोध है कि: https://github.com/elasticsearch/elasticsearch/pull/4332/files

कारण आप बिना किसी नाम के लोगों को प्राप्त कर रहे हैं Michael यह है कि आप bool.should कर रहे हैं। इसमें OR-semantics है। यह पर्याप्त है कि एक मैच होता है, लेकिन स्कोरिंग के मुकाबले यह बेहतर होता है कि इससे मेल खाता है।

आखिरकार, एक ही शब्द में फ़िल्टर करने वाले सभी को संयोजित करना सबसे अच्छा तरीका नहीं है। उदाहरण के लिए, आप सटीक वर्तनी को नहीं जानते और बढ़ावा नहीं दे सकते हैं। आपको कई तरीकों से क्षेत्र को संसाधित करने के लिए multi_field का उपयोग करना चाहिए।

Here's an example you can play with, कर्ल कमांड के साथ इसे फिर से बनाने के लिए। हालांकि, मैं पूरी तरह से "पोर्टर" स्टेमर का उपयोग करके छोड़ दूंगा। मैंने इसे दिखाने के लिए रखा कि mult_field कैसे काम करता है। मैच के संयोजन का उपयोग करके, अस्पष्टता और फोनेटिक मिलान के साथ मिलान करना आपको दूर ले जाना चाहिए। (सुनिश्चित करें कि आप ध्वन्यात्मक मिलान कर आप fuzziness की अनुमति नहीं देते हैं - या आप बेकार में फजी मिलान मिल जाएगा :-)

#!/bin/bash 

export ELASTICSEARCH_ENDPOINT="http://localhost:9200" 

# Create indexes 

curl -XPUT "$ELASTICSEARCH_ENDPOINT/play" -d '{ 
    "settings": { 
     "analysis": { 
      "text": [ 
       "Michael", 
       "Heaney", 
       "Heavey" 
      ], 
      "analyzer": { 
       "metaphone": { 
        "type": "custom", 
        "tokenizer": "standard", 
        "filter": [ 
         "my_metaphone" 
        ] 
       }, 
       "porter": { 
        "type": "custom", 
        "tokenizer": "standard", 
        "filter": [ 
         "lowercase", 
         "porter_stem" 
        ] 
       } 
      }, 
      "filter": { 
       "my_metaphone": { 
        "encoder": "metaphone", 
        "replace": false, 
        "type": "phonetic" 
       } 
      } 
     } 
    }, 
    "mappings": { 
     "jr": { 
      "properties": { 
       "pty_surename": { 
        "type": "multi_field", 
        "fields": { 
         "pty_surename": { 
          "type": "string", 
          "analyzer": "simple" 
         }, 
         "metaphone": { 
          "type": "string", 
          "analyzer": "metaphone" 
         }, 
         "porter": { 
          "type": "string", 
          "analyzer": "porter" 
         } 
        } 
       } 
      } 
     } 
    } 
}' 


# Index documents 
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_bulk?refresh=true" -d ' 
{"index":{"_index":"play","_type":"jr"}} 
{"pty_surname":"Heaney"} 
{"index":{"_index":"play","_type":"jr"}} 
{"pty_surname":"Heavey"} 
' 

# Do searches 

curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d ' 
{ 
    "query": { 
     "bool": { 
      "should": [ 
       { 
        "bool": { 
         "should": [ 
          { 
           "match": { 
            "pty_surname": { 
             "query": "heavey" 
            } 
           } 
          }, 
          { 
           "match": { 
            "pty_surname": { 
             "query": "heavey", 
             "fuzziness": 1 
            } 
           } 
          }, 
          { 
           "match": { 
            "pty_surename.metaphone": { 
             "query": "heavey" 
            } 
           } 
          }, 
          { 
           "match": { 
            "pty_surename.porter": { 
             "query": "heavey" 
            } 
           } 
          } 
         ] 
        } 
       } 
      ] 
     } 
    } 
} 
' 
+0

धन्यवाद, एलेक्स।। मुझे इस जानकारी के चारों ओर अपना सिर मिलने दें और मैं वापस रिपोर्ट करूंगा। उत्तर बहुत अच्छी तरह से दिखता है। – Nate

+0

हमने अभी अस्पष्ट खोज पर एक लेख प्रकाशित किया है जो कि ब्याज भी हो सकता है: https://www.found.no/foundation/fuzzy-search/ –

+0

बुकमार्क करेगा। आपकी मदद के लिए बहुत बहुत धन्यवाद, मैंने बहुत कुछ सीखा है। – Nate

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