ตัวกรองที่ซ้อนกันของ elasticsearch ส่งคืนผลลัพธ์ที่ว่างเปล่า

ฉันมีการแมปนี้:

  "post": {
    "model": "Post",
    "properties": {
      "id": {
        "type": "integer"
      },
      "title": {
        "type": "string",
        "analyzer": "custom_analyzer",
        "boost": 5
      },
      "description": {
        "type": "string",
        "analyzer": "custom_analyzer",
        "boost": 4
      },
      "condition": {
        "type": "integer",
        "index": "not_analyzed"
      },
      "categories": {
        "type": "string",
        "index": "not_analyzed"
      },
      "seller": {
        "type": "nested",
        "properties": {
          "id": {
            "type": "integer",
            "index": "not_analyzed"
          },
          "username": {
            "type": "string",
            "analyzer": "custom_analyzer",
            "boost": 1
          },
          "firstName": {
            "type": "string",
            "analyzer": "custom_analyzer",
            "boost": 3
          },
          "lastName": {
            "type": "string",
            "analyzer": "custom_analyzer",
            "boost": 2
          }
        }
      },
      "marketPrice": {
        "type": "float",
        "index": "not_analyzed"
      },
      "currentPrice": {
        "type": "float",
        "index": "not_analyzed"
      },
      "discount": {
        "type": "float",
        "index": "not_analyzed"
      },
      "commentsCount": {
        "type": "integer",
        "index": "not_analyzed"
      },
      "likesCount": {
        "type": "integer",
        "index": "not_analyzed"
      },
      "featured": {
        "type": "boolean",
        "index": "not_analyzed"
      },
      "bumped": {
        "type": "boolean",
        "index": "not_analyzed"
      },
      "created": {
        "type": "date",
        "index": "not_analyzed"
      },
      "modified": {
        "type": "date",
        "index": "not_analyzed"
      }
    }
  }

และแบบสอบถามนี้:

GET /develop/_search?search_type=dfs_query_then_fetch
{
  "query": {
    "filtered" : {
        "query": {
          "bool": {
            "must": [
              { "match": { "title": "post" }}
            ]
          }
        },
        "filter": {
          "bool": { 
            "must": [
              {"term": {
                "featured": 0
              }},
              { 
              "nested": {
                "path": "seller",
                "filter": {
                  "bool": {
                    "must": [
                      { "term": { "seller.firstName": "Test 3" } }
                    ]
                  }
                },
                "_cache" : true
              }}
            ]
          } 
        }
    }
  },
  "sort": [
    {
      "_score":{
        "order": "desc"
      }
    },{
      "created": {
        "order": "desc"
      }
    }
  ],
  "track_scores": true
}

ฉันรอ 25 ผลลัพธ์เพราะฉันมี 25 โพสต์ที่จัดทำดัชนี แต่ฉันได้ชุดเปล่ามา ถ้าฉันลบตัวกรองที่ซ้อนกันทั้งหมดก็ใช้ได้ดี ฉันต้องการที่จะกรองวัตถุที่ซ้อนกันได้

แก้ไข:

ในการตั้งค่าของฉันฉันมี:

    "analyzer": {
      "custom_analyzer": {
        "type": "custom",
        "tokenizer": "nGram",
        "filter": [
          "stopwords",
          "asciifolding",
          "lowercase",
          "snowball",
          "english_stemmer",
          "english_possessive_stemmer",
          "worddelimiter"
        ]
      },
      "custom_search_analyzer": {
        "type": "custom",
        "tokenizer": "standard",
        "filter": [
          "stopwords",
          "asciifolding",
          "lowercase",
          "snowball",
          "english_stemmer",
          "english_possessive_stemmer",
          "worddelimiter"
        ]
      }
    }

สิ่งที่ฉันหายไปที่นี่

ขอบคุณ


person bitgandtter    schedule 05.01.2015    source แหล่งที่มา
comment
คุณสามารถโพสต์คำจำกัดความของคุณเกี่ยวกับ custom_analyzer ได้หรือไม่ วิธีการตั้งค่าอาจมีบางอย่างเกี่ยวข้องกับปัญหาของคุณ   -  person Sloan Ahrens    schedule 06.01.2015
comment
เฮ้ @SloanAhrens ฉันอัปเดตคำถามกับผู้วิเคราะห์ของฉัน   -  person bitgandtter    schedule 06.01.2015
comment
ฉันยังไม่สามารถตั้งค่าดัชนีเช่นของคุณเพื่อทดสอบได้ ดูเหมือนว่าคุณได้กำหนดตัวกรองแบบกำหนดเองไว้ด้วยใช่ไหม คุณสามารถโพสต์สิ่งเหล่านั้นด้วยได้ไหม? เอกสารตัวอย่างบางส่วนอาจเป็นประโยชน์เช่นกัน ค่อนข้างยากที่จะบอกคุณว่าปัญหาคืออะไรโดยไม่สามารถจำลองระบบของคุณได้   -  person Sloan Ahrens    schedule 06.01.2015
comment
ฉันสงสัยว่าด้วยการตั้งค่าปัจจุบันของคุณ { "term": { "seller.firstName": "Test 3" } } จะต้องเป็น { "term": { "seller.firstName": "test" } } หรืออะไรทำนองนั้น หรือคุณจะต้องปรับเครื่องวิเคราะห์/การแมปของคุณ แต่ก็ยากที่จะพูดอย่างแน่นอนหากไม่มีการทดสอบโดยตรง   -  person Sloan Ahrens    schedule 06.01.2015
comment
@SloanAhrens สำหรับคำถามนี้ stackoverflow.com/ คำถาม/27493452/ ฉันโพสต์ข้อมูลและการทำแผนที่เดียวกัน แต่ด้วยเหตุผลอื่น มันเหมือนกัน   -  person bitgandtter    schedule 06.01.2015


คำตอบ (1)


เวอร์ชันสั้น: ลองทำเช่นนี้ (หลังจากอัปเดตชื่อปลายทางและดัชนี):

curl -XPOST "http://localhost:9200/my_index/_search?search_type=dfs_query_then_fetch" -d'
{
   "query": {
      "filtered": {
         "query": {
            "bool": {
               "must": [
                  {
                     "match": {
                        "title": "post"
                     }
                  }
               ]
            }
         },
         "filter": {
            "bool": {
               "must": [
                  {
                     "nested": {
                        "path": "seller",
                        "filter": {
                           "bool": {
                              "must": [
                                 {
                                    "terms": {
                                       "seller.firstName": [
                                          "test",
                                          "3"
                                       ],
                                       "execution": "and"
                                    }
                                 }
                              ]
                           }
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}'

มันใช้งานได้สำหรับฉันด้วยการตั้งค่าเวอร์ชันที่เรียบง่ายของคุณ ฉันจะโพสต์การแก้ไขพร้อมคำอธิบายที่ยาวขึ้นในอีกสักครู่

แก้ไข: เวอร์ชันยาว:

ปัญหากับข้อความค้นหาของคุณคือตัววิเคราะห์รวมกับตัวกรอง term ในข้อความค้นหาของคุณ ตัววิเคราะห์ของคุณกำลังแบ่งข้อความของฟิลด์ firstName ออกเป็นโทเค็น ดังนั้น "Test 3" จึงกลายเป็นโทเค็น "test" และ "3" เมื่อคุณใช้ { "term": { "seller.firstName": "Test 3" } } สิ่งที่คุณพูดคือ ให้ค้นหาเอกสารที่หนึ่งในโทเค็นสำหรับ "seller.firstName" คือ "Test 3" และไม่มีเอกสารใดๆ ที่เป็นจริง (ในความเป็นจริง ไม่สามารถระบุวิธีที่เครื่องวิเคราะห์ของคุณได้ ถูกตั้งค่าไว้) คุณสามารถใช้ "index": "not_analyzed" ในฟิลด์นั้น จากนั้นข้อความค้นหาของคุณจะใช้งานได้ หรือคุณสามารถใช้ตัวกรอง terms ตามที่ฉันแสดงไว้ด้านบน ฉันไปถึงที่นั่นได้อย่างไร:

ฉันเริ่มต้นด้วยคำจำกัดความของดัชนีที่คุณลิงก์ไว้ในความคิดเห็นของคุณ และทำให้มันง่ายขึ้นเล็กน้อยเพื่อให้อ่านง่ายขึ้นและยังคงรักษาประเด็นที่สำคัญไว้:

curl -XDELETE "http://localhost:9200/my_index"

curl -XPUT "http://localhost:9200/my_index" -d'
{
   "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 0,
      "analysis": {
         "filter": {
            "snowball": { "type": "snowball", "language": "English" },
            "english_stemmer": { "type": "stemmer", "language": "english" },
            "english_possessive_stemmer": { "type": "stemmer", "language": "possessive_english" },
            "stopwords": { "type": "stop",  "stopwords": [ "_english_" ] },
            "worddelimiter": { "type": "word_delimiter" }
         },
         "tokenizer": {
            "nGram": { "type": "nGram", "min_gram": 3, "max_gram": 20 }
         },
         "analyzer": {
            "custom_analyzer": {
               "type": "custom",
               "tokenizer": "nGram",
               "filter": [
                  "stopwords",
                  "asciifolding",
                  "lowercase",
                  "snowball",
                  "english_stemmer",
                  "english_possessive_stemmer",
                  "worddelimiter"
               ]
            },
            "custom_search_analyzer": {
               "type": "custom",
               "tokenizer": "standard",
               "filter": [
                  "stopwords",
                  "asciifolding",
                  "lowercase",
                  "snowball",
                  "english_stemmer",
                  "english_possessive_stemmer",
                  "worddelimiter"
               ]
            }
         }
      }
   },
   "mappings": {
      "posts": {
         "properties": {
            "title": {
               "type": "string",
               "analyzer": "custom_analyzer",
               "boost": 5
            },
            "seller": {
               "type": "nested",
               "properties": {
                  "firstName": {
                     "type": "string",
                     "analyzer": "custom_analyzer",
                     "boost": 3
                  }
               }
            }
         }
      }
   }
}'

จากนั้นฉันก็เพิ่มเอกสารทดสอบบางส่วน:

curl -XPUT "http://localhost:9200/my_index/posts/1" -d'
{"title": "post", "seller": {"firstName":"Test 1"}}'
curl -XPUT "http://localhost:9200/my_index/posts/2" -d'
{"title": "post", "seller": {"firstName":"Test 2"}}'
curl -XPUT "http://localhost:9200/my_index/posts/3" -d'
{"title": "post", "seller": {"firstName":"Test 3"}}'

จากนั้นรันการสืบค้นเวอร์ชันที่เรียบง่ายของคุณโดยที่โครงสร้างพื้นฐานยังคงเหมือนเดิม แต่มีตัวกรอง terms แทนที่จะเป็นตัวกรอง term:

curl -XPOST "http://localhost:9200/my_index/_search?search_type=dfs_query_then_fetch" -d'
{
   "query": {
      "filtered": {
         "query": {
            "bool": {
               "must": [
                  {
                     "match": {
                        "title": "post"
                     }
                  }
               ]
            }
         },
         "filter": {
            "bool": {
               "must": [
                  {
                     "nested": {
                        "path": "seller",
                        "filter": {
                           "bool": {
                              "must": [
                                 {
                                    "terms": {
                                       "seller.firstName": [
                                          "test",
                                          "3"
                                       ],
                                       "execution": "and"
                                    }
                                 }
                              ]
                           }
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}'
...
{
   "took": 5,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 6.085842,
      "hits": [
         {
            "_index": "my_index",
            "_type": "posts",
            "_id": "3",
            "_score": 6.085842,
            "_source": {
               "title": "post",
               "seller": {
                  "firstName": "Test 3"
               }
            }
         }
      ]
   }
}

ซึ่งดูเหมือนว่าจะคืนสิ่งที่คุณต้องการ

นี่คือรหัสที่ฉันใช้:

http://sense.qbox.io/gist/041dd929106d27ea606f48ce1f86076c52faec91

person Sloan Ahrens    schedule 05.01.2015
comment
ใช้งานได้ดี แต่ ES ไม่ควรทำเช่นนี้เพื่อฉันใช่ไหม ฉันจะระบุเครื่องวิเคราะห์เพื่อใช้ในตัวกรองได้อย่างไร เพราะถ้าฉันต้องทำการวิเคราะห์ข้อความค้นหา ตัวฉันเองก็อาจจะค่อนข้างยาก - person bitgandtter; 06.01.2015
comment
อ่านการแก้ไขที่ฉันเพิ่งทำและดูว่าคำตอบนั้นตอบคำถามของคุณหรือไม่ ถ้าไม่ฉันจะดูว่าฉันสามารถอัปเดตได้หรือไม่ ฉันคาดว่าคุณจะต้องการแก้ไขเครื่องวิเคราะห์ของคุณและ/หรือใช้ multi_field - person Sloan Ahrens; 06.01.2015
comment
ขอบคุณ Sloan หลังจากที่คุณเผยแพร่คำตอบ ฉันเข้าใจแล้วว่า custom_analyzer กำลังแยกฟิลด์ แต่สิ่งที่ฉันต้องการให้ใช้ custom_search_analyzer ในแบบสอบถาม ดังนั้นในขณะที่ใช้ตัวกรอง ES จะแยกข้อความด้วยตนเอง ดังนั้นฉันไม่ จำเป็นต้องแยกมันเองและสร้างแบบสอบถามด้วยวิธีนี้ ฉันมีคำถามอื่นที่มี multi_match: { query: post, fields: [title, description], analyser: custom_search_analyzer } ในนั้น สิ่งที่ฉันต้องการคือทำสิ่งที่คล้ายกัน - person bitgandtter; 06.01.2015
comment
ขออภัย ฉันไม่แน่ใจว่าฉันเข้าใจคำถามของคุณ คุณได้ลองสิ่งที่คุณแนะนำแล้วหรือยัง? บางทีมันอาจจะคุ้มค่าที่จะถามคำถาม StackOverflow อีกครั้งเกี่ยวกับเรื่องนี้ - person Sloan Ahrens; 06.01.2015
comment
ใช่ ฉันได้ลองแล้ว แต่ได้รับข้อผิดพลาดเนื่องจากไม่พบวิธีทำให้ตัวกรองใช้ตัววิเคราะห์ที่กำหนดเอง ฉันจะลองถามคำถามอื่น ขอบคุณ - person bitgandtter; 06.01.2015