2014年6月20日 星期五

[elasticsearch]range query depends on the field type



在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

沒有留言:

張貼留言