2013-03-15 10 views
12

मैं बिना किसी फ़ील्ड के एक बहु शब्द खोज से मिलान करने में सक्षम होना चाहता हूं, जहां प्रत्येक शब्द खोजा गया है फ़ील्ड के किसी भी में कोई संयोजन है। पकड़ है कि मैं query_string का उपयोग करने से बचाना चाहता हूं।बहु-फ़ील्ड, बहु-शब्द, बिना क्वेरी_स्ट्रिंग

curl -X POST "http://localhost:9200/index/document/1" -d '{"id":1,"firstname":"john","middlename":"clark","lastname":"smith"}' 
curl -X POST "http://localhost:9200/index/document/2" -d '{"id":2,"firstname":"john","middlename":"paladini","lastname":"miranda"}' 

मैं केवल दस्तावेज़ 1. मैच के लिए निम्न क्वेरी मैं क्या आवश्यकता है, लेकिन मैं नहीं बल्कि मामले में QUERY_STRING का उपयोग कर उपयोगकर्ता गुजरता "या" से बच जाएंगे 'जॉन स्मिथ' के लिए खोज करना चाहते हैं, "और" और अन्य उन्नत पैराम में से कोई भी। ।

क्वेरी पद व्याख्या "प्रक्रिया" क्वेरी एक के माध्यम से जाना नहीं है की मैच परिवार "यह फ़ील्ड नाम उपसर्गों का समर्थन नहीं करता, वाइल्डकार्ड:

curl -X GET 'http://localhost:9200/index/_search?per_page=10&pretty' -d '{ 
    "query": { 
    "query_string": { 
     "query": "john smith", 
     "default_operator": "AND", 
     "fields": [ 
     "firstname", 
     "lastname", 
     "middlename" 
     ] 
    } 
    } 
}' 
+0

मैं इस प्रश्न पर बार-बार आ रहा हूं। महान, सदाबहार सवाल! –

उत्तर

23

जो आप खोज रहे हैं वह multi-match query है, लेकिन यह आपके इच्छित तरीके से प्रदर्शन नहीं करता है।

के multi_match बनाम query_string के आउटपुट की तुलना करें।

यह सुनिश्चित करें कि सभी शर्तों कम से कम एक क्षेत्र में मौजूद कर देगा (ऑपरेटर and के साथ) multi_match:

curl -XGET 'http://127.0.0.1:9200/_validate/query?pretty=1&explain=true' -d ' 
{ 
    "multi_match" : { 
     "operator" : "and", 
     "fields" : [ 
     "firstname", 
     "lastname" 
     ], 
     "query" : "john smith" 
    } 
} 
' 

# { 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 1, 
#  "total" : 1 
# }, 
# "explanations" : [ 
#  { 
#   "index" : "test", 
#   "explanation" : "((+lastname:john +lastname:smith) | (+firstname:john +firstname:smith))", 
#   "valid" : true 
#  } 
# ], 
# "valid" : true 
# } 

जबकि query_string (default_operator AND के साथ) की जाँच करेगा कि प्रत्येक अवधि कम से कम एक क्षेत्र में मौजूद है:

curl -XGET 'http://127.0.0.1:9200/_validate/query?pretty=1&explain=true' -d ' 
{ 
    "query_string" : { 
     "fields" : [ 
     "firstname", 
     "lastname" 
     ], 
     "query" : "john smith", 
     "default_operator" : "AND" 
    } 
} 
' 

# { 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 1, 
#  "total" : 1 
# }, 
# "explanations" : [ 
#  { 
#   "index" : "test", 
#   "explanation" : "+(firstname:john | lastname:john) +(firstname:smith | lastname:smith)", 
#   "valid" : true 
#  } 
# ], 
# "valid" : true 
# } 

तो तुम प्राप्त करने के लिए आप क्या कर रहे हैं कुछ विकल्प हैं के बाद:

  1. Preparse खोज शब्द, प्रत्येक शब्द को निकालने के लिए query_string

  2. Preparse खोज शब्दों का उपयोग करने से पहले, वाइल्डकार्ड, आदि जैसी चीजों को दूर करने के लिए, तो शब्द

  3. उपयोग index_name प्रति एक multi_match क्वेरी उत्पन्न अपने नाम फ़ील्ड के लिए मैपिंग को अपने डेटा को एक फ़ील्ड में इंडेक्स करने के लिए, जिसे आप खोज के लिए उपयोग कर सकते हैं। (अपने स्वयं के कस्टम all क्षेत्र की तरह):

के रूप में इस प्रकार है:

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1' -d ' 
{ 
    "mappings" : { 
     "test" : { 
     "properties" : { 
      "firstname" : { 
       "index_name" : "name", 
       "type" : "string" 
      }, 
      "lastname" : { 
       "index_name" : "name", 
       "type" : "string" 
      } 
     } 
     } 
    } 
} 
' 

curl -XPOST 'http://127.0.0.1:9200/test/test?pretty=1' -d ' 
{ 
    "firstname" : "john", 
    "lastname" : "smith" 
} 
' 

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "match" : { 
     "name" : { 
      "operator" : "and", 
      "query" : "john smith" 
     } 
     } 
    } 
} 
' 

# { 
# "hits" : { 
#  "hits" : [ 
#   { 
#    "_source" : { 
#    "firstname" : "john", 
#    "lastname" : "smith" 
#    }, 
#    "_score" : 0.2712221, 
#    "_index" : "test", 
#    "_id" : "VJFU_RWbRNaeHF9wNM8fRA", 
#    "_type" : "test" 
#   } 
#  ], 
#  "max_score" : 0.2712221, 
#  "total" : 1 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 5, 
#  "total" : 5 
# }, 
# "took" : 33 
# } 

नोट तथापि, कि firstname और lastname स्वतंत्र रूप से नहीं रह गया हैं। दोनों क्षेत्रों के लिए डेटा को name में अनुक्रमित किया गया है।

आप path पैरामीटर के साथ multi-fields इस्तेमाल कर सकते हैं उन दोनों को स्वतंत्र रूप से और एक साथ खोजने योग्य बनाना, इस प्रकार है:

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1' -d ' 
{ 
    "mappings" : { 
     "test" : { 
     "properties" : { 
      "firstname" : { 
       "fields" : { 
        "firstname" : { 
        "type" : "string" 
        }, 
        "any_name" : { 
        "type" : "string" 
        } 
       }, 
       "path" : "just_name", 
       "type" : "multi_field" 
      }, 
      "lastname" : { 
       "fields" : { 
        "any_name" : { 
        "type" : "string" 
        }, 
        "lastname" : { 
        "type" : "string" 
        } 
       }, 
       "path" : "just_name", 
       "type" : "multi_field" 
      } 
     } 
     } 
    } 
} 
' 

curl -XPOST 'http://127.0.0.1:9200/test/test?pretty=1' -d ' 
{ 
    "firstname" : "john", 
    "lastname" : "smith" 
} 
' 

any_name क्षेत्र सर्च कर रहे हैं काम करता है:

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "match" : { 
     "any_name" : { 
      "operator" : "and", 
      "query" : "john smith" 
     } 
     } 
    } 
} 
' 

# { 
# "hits" : { 
#  "hits" : [ 
#   { 
#    "_source" : { 
#    "firstname" : "john", 
#    "lastname" : "smith" 
#    }, 
#    "_score" : 0.2712221, 
#    "_index" : "test", 
#    "_id" : "Xf9qqKt0TpCuyLWioNh-iQ", 
#    "_type" : "test" 
#   } 
#  ], 
#  "max_score" : 0.2712221, 
#  "total" : 1 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 5, 
#  "total" : 5 
# }, 
# "took" : 11 
# } 

john AND smith नहीं करता है के लिए खोज firstname ' टी काम:

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "match" : { 
     "firstname" : { 
      "operator" : "and", 
      "query" : "john smith" 
     } 
     } 
    } 
} 
' 

# { 
# "hits" : { 
#  "hits" : [], 
#  "max_score" : null, 
#  "total" : 0 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 5, 
#  "total" : 5 
# }, 
# "took" : 2 
# } 

लेकिन खोज firstname सिर्फ john के लिए सही ढंग से काम करता है:

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "match" : { 
     "firstname" : { 
      "operator" : "and", 
      "query" : "john" 
     } 
     } 
    } 
} 
' 

# { 
# "hits" : { 
#  "hits" : [ 
#   { 
#    "_source" : { 
#    "firstname" : "john", 
#    "lastname" : "smith" 
#    }, 
#    "_score" : 0.30685282, 
#    "_index" : "test", 
#    "_id" : "Xf9qqKt0TpCuyLWioNh-iQ", 
#    "_type" : "test" 
#   } 
#  ], 
#  "max_score" : 0.30685282, 
#  "total" : 1 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 5, 
#  "total" : 5 
# }, 
# "took" : 3 
# } 
0

मुझे लगता है कि" मैच "क्वेरी के लिए आप क्या देख रहे है पात्रों, या अन्य "अग्रिम" विशेषताएं। इस कारण से, विफल होने की संभावनाएं बहुत छोटी/मौजूद नहीं हैं, और यह एक उत्कृष्ट व्यवहार प्रदान करता है जब यह केवल एक क्वेरी व्यवहार के रूप में उस पाठ का विश्लेषण और चलाने के लिए आता है (जो आमतौर पर होता है टेक्स्ट सर्च बॉक्स करता है) "

http://www.elasticsearch.org/guide/reference/query-dsl/match-query.html

1

मैं नहीं बल्कि उपयोगकर्ता गुजरता "या", "और" मामले में QUERY_STRING उपयोग करने से बचें हैं और अन्य उन्नत पैरामीटर के किसी भी।

मेरे अनुभव में, बैकस्लैश के साथ विशेष वर्णों से बचने का एक सरल और प्रभावी समाधान है। सूची http://lucene.apache.org/core/4_5_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package_description, प्लस और/OR/NOT/TO प्रलेखन में पाई जा सकती है।

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