filter bersarang elasticsearch mengembalikan hasil kosong

Saya memiliki pemetaan ini:

  "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"
      }
    }
  }

Dan pertanyaan ini:

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
}

Saya menunggu 25 hasil karena saya memiliki 25 posting yang terindeks. Tapi saya mendapatkan satu set kosong. Jika saya menghapus filter bersarang, semuanya berfungsi dengan baik. Saya ingin dapat memfilter objek bersarang

Sunting:

Dalam pengaturan saya, saya punya:

    "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"
        ]
      }
    }

Apa yang saya lewatkan di sini.

Terima kasih


person bitgandtter    schedule 05.01.2015    source sumber
comment
Bisakah Anda memposting definisi Anda tentang custom_analyzer? Cara pengaturannya mungkin ada hubungannya dengan masalah Anda.   -  person Sloan Ahrens    schedule 06.01.2015
comment
hai @SloanAhrens saya memperbarui pertanyaan dengan analisa saya   -  person bitgandtter    schedule 06.01.2015
comment
Saya masih belum dapat menyiapkan indeks seperti milik Anda untuk mengujinya. Sepertinya Anda juga telah menentukan beberapa filter khusus? Bisakah Anda mempostingnya juga? Beberapa contoh dokumen mungkin juga berguna. Sangat sulit untuk memberitahu Anda apa masalahnya tanpa bisa mensimulasikan sistem Anda.   -  person Sloan Ahrens    schedule 06.01.2015
comment
Namun kecurigaan saya adalah, dengan pengaturan Anda saat ini, { "term": { "seller.firstName": "Test 3" } } harus { "term": { "seller.firstName": "test" } }, atau yang serupa. Atau Anda perlu menyesuaikan alat analisa/pemetaan Anda. Namun sulit untuk memastikannya tanpa melakukan pengujian secara langsung.   -  person Sloan Ahrens    schedule 06.01.2015
comment
@SloanAhrens pada pertanyaan ini stackoverflow.com/ question/27493452/ saya memposting data dan pemetaan yang sama tetapi untuk alasan yang berbeda, sama saja   -  person bitgandtter    schedule 06.01.2015


Jawaban (1)


Versi singkat: coba ini (setelah memperbarui titik akhir dan nama indeks):

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"
                                    }
                                 }
                              ]
                           }
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}'

Ini berhasil bagi saya, dengan versi pengaturan Anda yang disederhanakan. Saya akan memposting editan dengan penjelasan yang lebih panjang sebentar lagi.

EDIT: versi panjang:

Masalah dengan kueri Anda adalah penganalisis yang dikombinasikan dengan filter term dalam kueri Anda. Penganalisis Anda memecah teks bidang firstName menjadi token; jadi "Test 3" menjadi token "test" dan "3". Saat Anda menggunakan { "term": { "seller.firstName": "Test 3" } } apa yang Anda katakan adalah, temukan dokumen yang salah satu tokennya untuk "seller.firstName" adalah "Test 3", dan tidak ada dokumen yang benar (pada kenyataannya, tidak ada cara penganalisis Anda sudah diatur). Anda dapat menggunakan "index": "not_analyzed" pada bidang itu dan kueri Anda akan berfungsi, atau Anda dapat menggunakan filter terms seperti yang saya tunjukkan di atas. Begini cara saya sampai di sana:

Saya mulai dengan definisi indeks yang Anda tautkan dalam komentar Anda, dan menyederhanakannya sedikit agar lebih mudah dibaca dan tetap mempertahankan masalah penting:

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
                  }
               }
            }
         }
      }
   }
}'

Lalu saya menambahkan beberapa dokumen pengujian:

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"}}'

Kemudian jalankan versi sederhana dari kueri Anda dengan struktur dasar yang masih utuh, tetapi dengan filter terms dan bukan filter 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"
               }
            }
         }
      ]
   }
}

yang sepertinya mengembalikan apa yang Anda inginkan.

Ini kode yang saya gunakan:

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

person Sloan Ahrens    schedule 05.01.2015
comment
Bagus sekali, tapi ES tidak seharusnya melakukan ini untuk saya? bagaimana cara menentukan penganalisis yang akan digunakan dalam filter? karena jika saya harus melakukan analisis teks pencarian sendiri bisa jadi cukup sulit - person bitgandtter; 06.01.2015
comment
Baca hasil edit yang baru saja saya buat dan lihat apakah itu menjawab pertanyaan Anda. Jika tidak, saya akan melihat apakah saya dapat memperbaruinya. Saya berharap Anda ingin memodifikasi penganalisis Anda, dan/atau menggunakan multi_field. - person Sloan Ahrens; 06.01.2015
comment
Terima kasih Sloan, setelah Anda mempublikasikan jawabannya saya mendapat gagasan bahwa custom_analyzer itu membagi bidang, tetapi yang saya inginkan adalah menggunakan custom_search_analyzer pada kueri jadi pada saat menggunakan filter ES membagi teks untuk itu sendiri jadi saya tidak perlu membaginya sendiri dan membuat kueri dengan cara ini. Saya memiliki pertanyaan lain dengan multi_match: { query: post, field: [judul, deskripsi], penganalisis: custom_search_analyzer } di dalamnya yang saya inginkan adalah melakukan hal serupa - person bitgandtter; 06.01.2015
comment
Maaf, saya tidak yakin saya memahami pertanyaan Anda. Sudahkah Anda mencoba apa yang Anda sarankan? Mungkin ada baiknya mengajukan pertanyaan StackOverflow lain tentang hal itu? - person Sloan Ahrens; 06.01.2015
comment
Ya, saya mencobanya tetapi saya mendapatkan kesalahan karena saya tidak menemukan cara untuk membuat filter menggunakan penganalisis khusus. Saya akan mencoba dengan pertanyaan lain. Terima kasih - person bitgandtter; 06.01.2015