在elasticsearch 使用 range query時,是根據 field type 也就是欄位的類別來決定對此欄位做怎樣的操作。
若是 string type 就是用 TermRangeQuery
若是 number / data 就使用 NumericRangeQuery
舉個例子來看,
- 建立 index
PUT /my_index/
- put type mapping
logs 這個type有兩個 field,一個是name把type定成 string。另一個是nid 設定成 integer type。
PUT /my_index/logs/_mapping
{
"properties": {
"name": {
"type": "string"
},
"nid": {
"type": "integer"
}
}
}
- 分別 index 兩筆 records
POST /my_index/logs
{
"name":"pc","nid":100
}
POST /my_index/logs
{
"name":"pc2","nid":"100"
}
第一筆,type 都與 mapping相同
第二筆,type 與 mapping 有相同不同,但是在索引時,他會盡量幫我們做一個casting檢查,但是並不會改變 _source的內容。也就是說,elasticsearch 在拿 document 每個欄位出來 index 值時,他會根據 mapping 去做parse 。
GET /my_index/logs/_search
{
"query": {
"match_all": {}
}
}
respose:
{
"took": 18,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "my_index",
"_type": "logs",
"_id": "-ph1-zIoR-eYuuxnctYL_w",
"_score": 1,
"_source": {
"name": "pc2",
"nid": "100"
}
},
{
"_index": "my_index",
"_type": "logs",
"_id": "x4mLJi0vR_iiR9v2l7BiAg",
"_score": 1,
"_source": {
"name": "pc",
"nid": 100
}
}
]
}
}
- 如果是 index 時的 欄位 type 與 mapping 不同時
POST /my_index/logs
{
"name":"pc2","nid":"abc"
}
response:
{
"error": "MapperParsingException[failed to parse [nid]]; nested: NumberFormatException[For input string: \"abc\"]; ",
"status": 400
}
- 因為不能 cast 丟出 Exception
org.elasticsearch.index.mapper.MapperParsingException: failed to parse [nid]
at org.elasticsearch.index.mapper.core.AbstractFieldMapper.parse(AbstractFieldMapper.java:418)
at org.elasticsearch.index.mapper.object.ObjectMapper.serializeValue(ObjectMapper.java:637)
at org.elasticsearch.index.mapper.object.ObjectMapper.parse(ObjectMapper.java:490)
at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:515)
at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:462)
at org.elasticsearch.index.shard.service.InternalIndexShard.prepareCreate(InternalIndexShard.java:373)
at org.elasticsearch.action.index.TransportIndexAction.shardOperationOnPrimary(TransportIndexAction.java:203)
at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction.performOnPrimary(TransportShardReplicationOperationAction.java:534)
at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction$1.run(TransportShardReplicationOperationAction.java:433)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NumberFormatException: For input string: "abc"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at org.elasticsearch.common.xcontent.support.AbstractXContentParser.intValue(AbstractXContentParser.java:126)
at org.elasticsearch.index.mapper.core.IntegerFieldMapper.innerParseCreateField(IntegerFieldMapper.java:307)
at org.elasticsearch.index.mapper.core.NumberFieldMapper.parseCreateField(NumberFieldMapper.java:224)
at org.elasticsearch.index.mapper.core.AbstractFieldMapper.parse(AbstractFieldMapper.java:408)
... 11 more
ref:
Matches documents with fields that have terms within a certain range. The type of the Lucene query depends on the field type, for
string
fields, the TermRangeQuery
, while for number/date fields, the query is a NumericRangeQuery
.Range Query
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-range-query.html
沒有留言:
張貼留言