Hello,
I discovered elasticsearch a few weeks ago and have found some time to
give it a try. I tried yesterday to use it to index some data that I
have in a database, and query this data using some constraints.
Say I have a database of products :
Products
- id : integer
- name : string
- date : date
- price : float
- items_available : integer
I created the index "testindex" using the mapping API, here is what I
find in the logs :
Put mapping [product] with source [{
"product" : {
"type" : "object",
"dynamic" : true,
"enabled" : true,
"pathType" : "full",
"dateFormats" : [ "dateOptionalTime" ],
"boostField" : {
"name" : "_boost"
},
"properties" : {
"id" : {
"type" : "integer",
"indexName" : "id",
"index" : "not_analyzed",
"store" : "yes",
"termVector" : "no",
"boost" : 1.0,
"omitNorms" : true,
"omitTermFreqAndPositions" : true,
"precisionStep" : 4
},
"price" : {
"type" : "float",
"indexName" : "price",
"index" : "not_analyzed",
"store" : "yes",
"termVector" : "no",
"boost" : 1.0,
"omitNorms" : true,
"omitTermFreqAndPositions" : true,
"precisionStep" : 4
},
"items_available" : {
"type" : "integer",
"indexName" : "items_available",
"index" : "not_analyzed",
"store" : "yes",
"termVector" : "no",
"boost" : 1.0,
"omitNorms" : true,
"omitTermFreqAndPositions" : true,
"precisionStep" : 4
},
"name" : {
"type" : "string",
"indexName" : "name",
"index" : "analyzed",
"store" : "yes",
"termVector" : "no",
"boost" : 1.0,
"omitNorms" : false,
"omitTermFreqAndPositions" : false
},
"date" : {
"type" : "date",
"indexName" : "date",
"index" : "not_analyzed",
"store" : "yes",
"termVector" : "no",
"boost" : 1.0,
"omitNorms" : true,
"omitTermFreqAndPositions" : true,
"precisionStep" : 4,
"format" : "YYYY-MM-dd"
}
}
}
}]
This is what I expect, so until here everything is fine. I index some
products :
curl -XPUT 'http://localhost:9200/testindex/product/1' -d
'{"name":"product1","date":"2010-03-01","price":12.7,"items_available":
2}'
curl -XPUT 'http://localhost:9200/testindex/product/2' -d
'{"name":"product2","date":"2010-03-01","price":30.2,"items_available":
7}'
curl -XPUT 'http://localhost:9200/testindex/product/3' -d
'{"name":"product3","date":"2010-03-01","price":50,"items_available":
6}'
curl -XPUT 'http://localhost:9200/testindex/product/4' -d
'{"name":"product4","date":"2010-03-01","price":69.2,"items_available":
5}'
curl -XPUT 'http://localhost:9200/testindex/product/5' -d
'{"name":"product5","date":"2010-03-01","price":85.4,"items_available":
10}'
curl -XPUT 'http://localhost:9200/testindex/product/6' -d
'{"name":"product6","date":"2010-03-01","price":100,"items_available":
1}'
If I try to retrieve the products in a certain price range, it works
well :
curl -XGET 'http://localhost:9200/testindex/product/_search' -d
'{"query":{"range":{"price":{"from":30,"to":
60,"includeLower":true,"includeUpper":true}}}}'
My problem is when I try to retrieve the products in a certain price
range and with a certain name. Here is what I do :
curl -XGET 'http://localhost:9200/testindex/product/_search' -d
'{"query":{"term":{"name":"product3"},"range":{"price":{"from":30,"to":
60,"includeLower":true,"includeUpper":true}}}}'
This returns an error :
{"_shards":{"total":5,"successful":0,"failed":5,"failures":
[{"index":"testindex","shardId":
3,"reason":"SearchParseException[[testindex][3]:
query[name:product3],from[-1],size[-1]: Parse Failure [Failed to parse
[{"query":{"term":{"name":"product3"},"range":{"price":
{"from":30,"to":60,"includeLower":true,"includeUpper
":true}}}}]]]; nested: SearchParseException[[testindex][3]:
query[name:product3],from[-1],size[-1]: Parse Failure [No parser for
element [price]]]; "},{"index":"testindex","shardId":
1,"reason":"SearchParseException[[testindex][1]:
query[name:product3],from[-1],size[-1]: Parse Failure [Failed to parse
[{"query":{"term":{"name":"product3"},"range":{"price":
{"from":30,"to":60,"includeLower":true,"includeUpper
":true}}}}]]]; nested: SearchParseException[[testindex][1]:
query[name:product3],from[-1],size[-1]: Parse Failure [No parser for
element [price]]]; "},{"reason":"Unknown"},{"reason":"Unknown"},
{"reason":"Unknown"}]},"hits":{"total":0,"hits":[]}}
My assumption is that it is not possible to mix term and range
queries. Therefore, I tried to use a filteredQuery :
curl -XGET 'http://localhost:9200/testindex/product/_search' -d
'{"filteredQuery":{"query":{"term":{"name":"product3"}},"filter":
{"range":{"price":{"from":30,"to":60}}}}}'
Here in a more "readable" form :
{
"filteredQuery" : {
"query" : {
"term" : { "name" : "product3" }
},
"filter" : {
"range" : {
"price" : { "from" : 30, "to" : 60 }
}
}
}
}
And this wuary also laucnehs an exception, even if it is quite close
to the sample query in the documentation at
http://www.elasticsearch.com/docs/elasticsearch/rest_api/query_dsl/#Filtered_Query
I there something I am doing wrong ? How should I write this (rather
simple) query ?
Regards and kudos for elasticsearch !
Xavier