18

假设在我的弹性搜索索引中,我有一个名为“dots”的字段,其中包含一串标点符号分隔的单词(例如“first.second.third”)。

我需要搜索例如“first.second”,然后获取其“dots”字段包含正好是“first.second”或以“first.second.”开头的字符串的所有条目。

我无法理解文本查询的工作原理,至少我无法创建一个可以完成这项工作的查询。

4

5 回答 5

23

Elasticsearch 具有专为此类用例创建的Path Hierarchy Tokenizer 。以下是如何为您的索引设置它的示例:

# Create a new index with custom path_hierarchy analyzer 
# See http://www.elasticsearch.org/guide/reference/index-modules/analysis/pathhierarchy-tokenizer.html
curl -XPUT "localhost:9200/prefix-test" -d '{
    "settings": {
        "analysis": {
            "analyzer": {
                "prefix-test-analyzer": {
                    "type": "custom",
                    "tokenizer": "prefix-test-tokenizer"
                }
            },
            "tokenizer": {
                "prefix-test-tokenizer": {
                    "type": "path_hierarchy",
                    "delimiter": "."
                }
            }
        }
    },
    "mappings": {
        "doc": {
            "properties": {
                "dots": {
                    "type": "string",
                    "analyzer": "prefix-test-analyzer",
                    //"index_analyzer": "prefix-test-analyzer", //deprecated
                    "search_analyzer": "keyword"
                }
            }
        }
    }
}'
echo
# Put some test data
curl -XPUT "localhost:9200/prefix-test/doc/1" -d '{"dots": "first.second.third"}'
curl -XPUT "localhost:9200/prefix-test/doc/2" -d '{"dots": "first.second.foo-bar"}'
curl -XPUT "localhost:9200/prefix-test/doc/3" -d '{"dots": "first.baz.something"}'
curl -XPOST "localhost:9200/prefix-test/_refresh"
echo
# Test searches. 
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true" -d '{
    "query": {
        "term": {
            "dots": "first"
        }
    }
}'
echo
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true" -d '{
    "query": {
        "term": {
            "dots": "first.second"
        }
    }
}'
echo
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true" -d '{
    "query": {
        "term": {
            "dots": "first.second.foo-bar"
        }
    }
}'
echo
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true&q=dots:first.second"
echo
于 2012-08-26T01:46:40.203 回答
3

正如 elasticsearch文档中所指出的,还有一种更简单的方法:

只需使用:

{
    "text_phrase_prefix" : {
        "fieldname" : "yourprefix"
    }
}

或从 0.19.9 开始:

{
    "match_phrase_prefix" : {
        "fieldname" : "yourprefix"
    }
}

代替:

{   
    "prefix" : { 
        "fieldname" : "yourprefix" 
}
于 2014-01-14T16:20:15.213 回答
2

看看前缀查询

$ curl -XGET 'http://localhost:9200/index/type/_search' -d '{
    "query" : {
        "prefix" : { "dots" : "first.second" }
    }
}'
于 2012-08-24T23:04:06.283 回答
1

您应该使用 commodin chars 进行查询,如下所示:

$ curl -XGET http://localhost:9200/myapp/index -d '{
    "dots": "first.second*"
}'

有关语法的更多示例:http: //lucene.apache.org/core/old_versioned_docs/versions/2_9_1/queryparsersyntax.html

于 2012-08-24T22:23:26.403 回答
1

我一直在寻找类似的解决方案 - 但只匹配一个前缀。我发现@imtov 的答案让我几乎到了那里,但有一个变化 - 切换分析器:

"mappings": {
    "doc": {
        "properties": {
            "dots": {
                "type": "string",
                "analyzer": "keyword",
                "search_analyzer": "prefix-test-analyzer"
            }
        }
    }
}

代替

"mappings": {
    "doc": {
        "properties": {
            "dots": {
                "type": "string",
                "index_analyzer": "prefix-test-analyzer",
                "search_analyzer": "keyword"
            }
        }
    }
}

这种方式添加:

'{"dots": "first.second"}'
'{"dots": "first.third"}'

将仅添加这些完整令牌,而不存储first, second,third令​​牌。

然而寻找任何一个

first.second.anyotherstring
first.second

将仅正确返回第一个条目:

'{"dots": "first.second"}'

不完全是您要求的,但不知何故相关,所以我认为可以帮助某人。

于 2016-02-15T16:34:48.053 回答