0

我正在尝试弹性搜索,它看起来很棒!

但是,我注意到一个非常不舒服的问题,在包含hello world如果我搜索hello wo返回没有结果的字段中!

为什么会这样?

放置我的配置(FOSElasticaBundle):

fos_elastica:
clients:
    default: { host: localhost, port: 9200 }
serializer:
    callback_class: FOS\ElasticaBundle\Serializer\Callback
    serializer: serializer
indexes:
    website:
        client: default
        settings:
            index:
                analysis:
                    analyzer:
                        custom_search_analyzer:
                            type: custom
                            tokenizer: standard
                            filter   : [standard, worddelimiter, stopwords, snowball, lowercase, asciifolding]
                        custom_index_analyzer:
                            type: custom
                            tokenizer: nGram
                            filter   : [standard, worddelimiter, stopwords, snowball, lowercase, asciifolding]
                    filter:
                        stopwords:
                            type:      stop
                            stopwords: [_italian_]
                            ignore_case : true
                        worddelimiter :
                            type:       word_delimiter
                    tokenizer:
                        nGram:
                          type:     nGram
                          min_gram: 1
                          max_gram: 20
        types:
            structure:
                mappings:
                    name: { boost: 9, search_analyzer: custom_search_analyzer, index_analyzer: custom_index_analyzer, type: string }

关于如何解决的任何想法?

编辑 这里我的查询:

{
  query: {
    bool: {
        must: [ ]
        must_not: [ ]
        should: [
            {
                term: {
                    structure.name: hello wo
                }
            }
        ]
    }
}
  from: 0
  size: 10
  sort: [ ]
  facets: { }
}

编辑 2

好吧,我不明白这种行为......

现在我运行这个查询:

{
    query: {
        bool: {
            must: [
            {
                term: {
                    structure.name: hello
                }
            }
            {
                term: {
                    structure.name: wo
                }
            }
            ]
            must_not: [ ]
            should: [ ]
        }
    }
    from: 0
    size: 10
    sort: [ ]
    facets: { }
}

这个查询是我想要的结果,但是我不明白将一个必须与两个词和两个必须与每个人都一个词有什么区别!

我可以解释这种行为吗?

4

1 回答 1

4

好吧,我可能需要向您解释它是如何工作的

当您索引文本时,弹性搜索将尝试将其拆分为术语,如果分析文本(如其在您的映射中),因此在您的情况下,“hello world”将受到两个术语“hello”和“world”的影响,当您执行术语时搜索您写的术语 hello world 不符合您的两个术语中的任何一个。

为避免吐出术语,您可以在映射中设置不分析字段名称,则不会吐出两个单词,并将作为一个标记处理。

其他解决方案是你可以多词查询

{
  "query": {
    "terms": {
      "structure.name": [
        "world",
        "hello"
      ]
    }
  }
}

此外,当您使用 query_string 时,它会返回结果,因为它具有不同的算法。

因此,取决于您的需要,您应该使用不同的查询,但是要按名称搜索,您应该使用 query_string,如果要过滤,则应该使用术语,比如 categoryId、标签和类似的东西。

于 2014-01-31T10:02:28.200 回答