Related
I have the index as below.
{
"id": {
"type": "keyword"
},
"title": {
"type": "text"
},
"comments": {
"type": "nested"
}
}
And I put some docs as below.
{
"id": 1,
"title": "Types",
"comments": [
{
"id": 113,
"contents": "Number"
},
{
"id": 2005,
"contents": "String"
},
{
"id": 317,
"contents": "Boolean"
}
]
}
{
"id": 2,
"title": "Animals",
"comments": [
{
"id": 45,
"contents": "Dog"
},
{
"id": 175,
"contents": "Cat"
},
{
"id": 26,
"contents": "Pig"
}
]
}
{
"id": 3,
"title": "Colors",
"comments": [
{
"id": 97,
"contents": "Red"
},
{
"id": 28,
"contents": "Green"
},
{
"id": 56,
"contents": "Blue"
}
]
}
When I use a nested query as below that the total count is just 3 but I want to get the 9 (All about nested properties).
{
"query": {
"nested": {
"path": "comment",
"query": {
"match_all": {}
}
}
}
}
I got the result as below.
{
"hits": {
"total": 3,
"hits": [
{
"_source": {
"id": 1,
"title": "Types",
"comments": [...]
}
},
{
"_source": {
"id": 2,
"title": "Animals",
"comments": [...]
}
},
{
"_source": {
"id": 3,
"title": "Colors",
"comments": [...]
}
}
]
}
}
But I wanted the result is like below format.
{
"hits": {
"total": 9,
"hits": [
{
"_source": {
"id": 113,
"contents": "Number"
}
},
...,
{
"_source": {
"id": 56,
"contents": "Blue"
}
}
]
}
}
How should I write the query to get the only 9 nested properties as I wanted result like above?
You need to use nested inner_hits like this:
{
"_source": false, <-- add this to prevent the parent doc from showing up
"query": {
"nested": {
"path": "comment",
"query": {
"match_all": {}
},
"inner_hits": {} <-- and this to only show the matching nested documents
}
}
}
I am trying to persist some objects that have a composite id. If I am only sending an array with one element it works fine, but it the array has more than one it throws an exception when saving the first one. public boolean
addParamsToChart(List<ChartParams> chartParams, Long chartId) {
List<ChartParams> chartParamsList = new ArrayList<>();
for(ChartParams chartParam: chartParams) {
ChartParamsId id = new ChartParamsId();
// id.setChartId(chartId);
id.setChartId(chartParam.getChart().getId());
id.setParamId(chartParam.getParam().getId());
id.setContextSourceId(chartParam.getContextSource().getId());
chartParam.setChartParamsId(id);
if(chartParamsRepository.save(chartParams) !=null) {
chartParamsList.add(chartParam);
}
}
if(chartParamsList.size()!=chartParams.size()) {
// something went wrong, delete previous inserted
deleteChartParams(chartParamsList);
chartRepository.delete(chartId);
return false;
}
return true;
}
[{
"chart": {
"id": 49,
"cv": {
"id": 1,
"name": "Money",
"category": {
"id": 1,
"name": "Euros"
},
"definition": "\"European curreny.\" [EU:euro]",
"enabled": true,
"cvid": "CC:1010"
},
"accountType": {
"id": 1,
"name": "saving"
},
"name": "Euro saving charts"
},
"param": {
"id": 8,
"name": "Totals",
"isFor": "Currency"
},
"contextSource": {
"id": 3,
"name": "euro",
"internal": "eu",
"abbreviatedName": "eu"
} }]
But for this having two objects inside instead of one is not working, throwing an exception at the first save.
[{
"chart": {
"id": 52,
"cv": {
"id": 55,
"name": "Stocks",
"category": {
"id": 1,
"name": "Stocks"
},
"definition": "\"General stocks.\" [GS:ST]",
"enabled": true,
"cvid": "ST:0111"
},
"accountType": {
"id": 1,
"name": "saving"
},
"name": "Stock saving chart"
},
"param": {
"id": 8,
"name": "Totals",
"isFor": "Currency"
},
"contextSource": {
"id": 6,
"name": "stock",
"internal": "st",
"abbreviatedName": "st"
} }, {
"chart": {
"id": 52,
"cv": {
"id": 55,
"name": "Stocks",
"category": {
"id": 1,
"name": "Stocks"
},
"definition": "\"General stocks.\" [GS:ST]",
"enabled": true,
"cvid": "ST:0111"
},
"accountType": {
"id": 1,
"name": "saving"
},
"name": "Stock saving chart"
},
"param": {
"id": 8,
"name": "Totals",
"isFor": "Currency"
},
"contextSource": {
"id": 7,
"name": "Sold stock",
"internal": "st_sold",
"abbreviatedSequence": "st_sold"
} }]
The exception I got is:
org.hibernate.id.IdentifierGenerationException: null id generated for:class eu.stocks.chart.chartParams.ChartParams
I am trying to search data from following indexed data
PUT /nested_test100/t/1
{
"title": "Nest eggs1",
"body": "Making your money work...",
"tags": [ "cash1", "shares1" ],
"comments": [
{
"name": "John Smith1",
"comment": "Great article1",
"age": 28,
"stars": 1,
"date": "2014-09-01"
},
{
"name": "Alice White1",
"comment": "More like this please1",
"age": 31,
"stars": 1,
"date": "2014-10-22"
}
]
}
PUT /nested_test100/t/2
{
"title": "Nest eggs2",
"body": "Making your money work...",
"tags": [ "cash", "shares" ],
"comments": [
{
"name": "John Smith2",
"comment": "Great article2",
"age": 30,
"stars": 2,
"date": "2014-09-01"
},
{
"name": "Alice White2",
"comment": "More like this please2",
"age": 31,
"stars": 2,
"date": "2014-10-22"
}
]
}
PUT /nested_test100/t/3
{
"title": "Nest eggs3",
"body": "Making your money work...",
"tags": [ "cash3", "shares3" ],
"comments": [
{
"name": "John Smith3",
"comment": "Great article3",
"age": 28,
"stars": 3,
"date": "2014-09-01"
},
{
"name": "Alice White3",
"comment": "More like this please3",
"age": 30,
"stars": 3,
"date": "2014-10-22"
}
]
}
GET /nested_test100/t/_search
what I want is to get title, body tags only and only comments having age=28.
How I should write query dsl for that.
what I have written is following
POST /nested_test100/t/_search
{
"fields" : ["title","comments.age","body","tags"],
"query" : {
"term" : { "comments.age" : "28" }
}
}
and its giving me data like this
"hits": [
{
"_index": "nested_test100",
"_type": "t",
"_id": "1",
"_score": 1,
"fields": {
"comments.age": [
28,
31
],
"title": [
"Nest eggs1"
],
"body": [
"Making your money work..."
],
"tags": [
"cash1",
"shares1"
]
}
},
{
"_index": "nested_test100",
"_type": "t",
"_id": "3",
"_score": 1,
"fields": {
"comments.age": [
28,
30
],
"title": [
"Nest eggs3"
],
"body": [
"Making your money work..."
],
"tags": [
"cash3",
"shares3"
]
}
}
]
but I don't want comments having age other than 28.
I am using elasticsearch version 1.7
Please use inner_hits to include nested inner objects as inner hits to a search hit.
The search request would be like :
POST test/_search
{
"query": {
"nested": {
"path": "comments",
"query": {
"match": {"comments.age" : 28}
},
"inner_hits": {}
}
}
}
P.S : You will need to map the comments as a nested field (as already mentioned by Val)
I'm having weird results on some nested objects that I can't understand.
I mean, in mapping the nested objects are all the same, they have an id and a tree id also, both are long and thats it, but profession and category do not return the expected values, but the others do (professionType, professionSubtype and attributeType).
So I got index mapped as:
Mapping:
{
"attribute-tree": {
"mappings": {
"attribute": {
"dynamic": "strict",
"properties": {
"attributeType": {
"properties": {
"id": {"type": "long"},
"tree": {"type": "long"}
}
},
"category": {
"properties": {
"id": {"type": "long"},
"tree": {"type": "long"}
}
},
"family": {"type": "long"},
"id": {"type": "long"},
"name": {
"type": "string",
"index": "not_analyzed"
},
"parentTree": {"type": "long"},
"profession": {
"properties": {
"id": {"type": "long"},
"tree": {"type": "long"}
}
},
"professionSubtype": {
"properties": {
"id": {"type": "long"},
"tree": {"type": "long"}
}
},
"professionType": {
"properties": {
"id": {"type": "long"},
"tree": {"type": "long"}
}
},
"sorter": {
"properties": {
"id": {"type": "long"},
"name": {
"type": "string",
"index": "not_analyzed"
},
"tree": {"type": "long"}
}
},
"suggester": {
"type": "completion",
"index_analyzer": "edgeNGram_analyzer",
"search_analyzer": "whitespace_analyzer",
"payloads": true,
"preserve_separators": true,
"preserve_position_increments": true,
"max_input_length": 50
},
"tree": {"type": "long"},
"type": {"type": "string"}
}
},
"division": {
// same as "attribute"
},
"profession-subtype": {
// same as "attribute"
},
"profession-type": {
// same as "attribute"
},
"profession": {
// same as "attribute"
},
"category": {
// same as "attribute"
}
}
}
}
If any kind of information is missing, please say
Thanks in advance
Example
Filtering by category.id:
POST /attribute-tree/_search
{
"size": 2,
"query": {
"filtered": {
"filter": {
"term": {"category.id": 1}
}
}
}
}
I get:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 31,
"max_score": 1,
"hits": [
{
"_index": "attribute-tree",
"_type": "category",
"_id": "4064",
"_score": 1,
"_source": {
"id": 1,
"tree": 4064,
"name": "Profession",
"type": "C",
"parentTree": 4063,
"profession": {
"id": null,
"tree": null
},
"professionType": {
"id": 1,
"tree": 1
},
"professionSubtype": {
"id": 6,
"tree": 4063
},
"category": {
"id": null,
"tree": null
},
"attributeType": {
"id": null,
"tree": null
},
"family": [
4063,
1
],
"suggester": {
"input": [
"Profession"
],
"output": "Profession"
},
"sorter": {
"name": "Profession",
"id": 1,
"tree": 4064
}
}
},
{
"_index": "attribute-tree",
"_type": "category",
"_id": "4083",
"_score": 1,
"_source": {
"id": 1,
"tree": 4083,
"name": "Profession",
"type": "C",
"parentTree": 4082,
"profession": {
"id": null,
"tree": null
},
"professionType": {
"id": 2,
"tree": 4072
},
"professionSubtype": {
"id": 8,
"tree": 4082
},
"category": {
"id": null,
"tree": null
},
"attributeType": {
"id": null,
"tree": null
},
"family": [
4082,
4072
],
"suggester": {
"input": [
"Profession"
],
"output": "Profession"
},
"sorter": {
"name": "Profession",
"id": 1,
"tree": 4083
}
}
}
]
}
}
Notice that on this example the category.id doesn't have the expected value (this is also valid for when it is 0 instead of null)
However I have nodes with category.id = 1:
POST /attribute-tree/_search
{
"size": 2,
"query": {
"filtered": {
"filter": {
"term": {"tree": 4}
}
}
}
}
Item:
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "attribute-tree",
"_type": "profession",
"_id": "4",
"_score": 1,
"_source": {
"id": 1,
"tree": 4,
"name": "A&R Administrator",
"type": "P",
"parentTree": 3,
"profession": {
"id": null,
"tree": null
},
"professionType": {
"id": 1,
"tree": 1
},
"professionSubtype": {
"id": 1,
"tree": 2
},
"category": {
"id": 1,
"tree": 3
},
"attributeType": {
"id": null,
"tree": null
},
"family": [
3,
2,
1
],
"suggester": {
"input": [
"A&R",
"Administrator"
],
"output": "A&R Administrator"
},
"sorter": {
"name": "A&R Administrator",
"id": 1,
"tree": 4
}
}
}
]
}
}
Filtering by professionType.id:
POST /attribute-tree/_search
{
"size": 2,
"query": {
"filtered": {
"filter": {
"term": {"professionSubtype.id": 1}
}
}
}
}
I get:
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3890,
"max_score": 1,
"hits": [
{
"_index": "attribute-tree",
"_type": "category",
"_id": "251",
"_score": 1,
"_source": {
"id": 4,
"tree": 251,
"name": "Medium",
"type": "C",
"parentTree": 2,
"profession": {
"id": null,
"tree": null
},
"professionType": {
"id": 1,
"tree": 1
},
"professionSubtype": {
"id": 1,
"tree": 2
},
"category": {
"id": null,
"tree": null
},
"attributeType": {
"id": null,
"tree": null
},
"family": [
2,
1
],
"suggester": {
"input": [
"Medium"
],
"output": "Medium"
},
"sorter": {
"name": "Medium",
"id": 4,
"tree": 251
}
}
},
{
"_index": "attribute-tree",
"_type": "profession",
"_id": "4",
"_score": 1,
"_source": {
"id": 1,
"tree": 4,
"name": "A&R Administrator",
"type": "P",
"parentTree": 3,
"profession": {
"id": null,
"tree": null
},
"professionType": {
"id": 1,
"tree": 1
},
"professionSubtype": {
"id": 1,
"tree": 2
},
"category": {
"id": 1,
"tree": 3
},
"attributeType": {
"id": null,
"tree": null
},
"family": [
3,
2,
1
],
"suggester": {
"input": [
"A&R",
"Administrator"
],
"output": "A&R Administrator"
},
"sorter": {
"name": "A&R Administrator",
"id": 1,
"tree": 4
}
}
}
]
}
}
Also tested as:
POST /attribute-tree/_search
{
"query":{
"filtered": {
"query": {"match_all":{}},
"filter": {
"nested": {
"path": "category",
"filter": {
"bool": {
"must": [
{"term": {"category.id": 1}}
]
}
}
}
}
}
}
}
But this gives an error
org.elasticsearch.index.query.QueryParsingException: [attribute-tree] [nested] nested object under path [category] is not of nested type
From the mapping it looks like the index has a type of category as well as a field in attribute type called category.
To allow for proper field resolution and disambiguate between field id in type category vs field category.id in type attribute you would need to specify the entire path to the field including the type i.e <type>.<fieldname>.
Example:
POST /attribute-tree/_search
{
"size": 2,
"query": {
"filtered": {
"filter": {
"term": {"attribute.category.id": 1}
}
}
}
}
This issue thread has more discussion with regard to this.
I can't seem to understand the QueryDSL for facets in elastic search. Below are my query object, and the mapping for my tags array. I'm trying to get these to put in a faceted navigation based on tags. Each "element" will have multiple tags associated in the tags array [Not all elements will have tags. Some will have an empty array.]. Each tag is an object with id and tag properties.
I've tried the nested facet approach and get the error that "tags is not nested", so then I try this below. I don't receive an error, but there is no facets object in the return JSON. I've been using this page for help: http://www.elasticsearch.org/guide/reference/api/search/facets/index.html.
Can anyone help me to format this correctly and understand the organization of these? I appreciate any help!
// this is my query object
{
"sort":{ "created_at":{ "order":"desc" } },
"query":{
"constant_score":{
"filter":{
"and":[
{ "missing":{ "field":"parent_id" } },
{ "missing":{ "field":"wall_id" } },
{ "term":{ "active":true } }
]
}
}
},
"facets":{
"tags":{ "terms":{ "field":"tags.tag" } }
}
}
// this is the mapping for the tags array
"tags":{
"type":"nested",
"include_in_parent":true,
"properties":{
"id":{ "type":"integer" },
"tag":{ "type":"string" }
}
},
I've tried hard to replicate this (using 0.18.5) but without any luck. Some details below. The first example tries to replicate what you describe. The second doesn't map tags as include_in_parent and uses the "nested" field in the facet request. As you can see, in both cases the facet is returned.
This leads me to believe that there is either something wrong with the rest of the mappings or some document (not the sample one you provided) that is causing issues.
When you tried the nested approach, perhaps you used "nested":"tags.tag" instead of "nested":"tags"?
(Un)Successful attempt #1:
Create index with mappings:
$ curl -XPOST 'http://localhost:9200/testindex/' -d '{
"mappings": {
"element": {
"properties": {
"tags": {
"type": "nested",
"include_in_parent": true,
"properties": {
"id": {
"type": "integer"
},
"tag": {
"type": "string"
}
}
}
}
}
}
}'
Index document:
$ curl -XPOST 'http://localhost:9200/testindex/element' -d '{
"element_id": 4682,
"parent_id": null,
"wall_id": null,
"username": "John Doe",
"avatar": "56f1bb0a96d02b90e5915ff38ea189ec.jpg",
"title": "Easy Chart is a great easy comparison chart maker for math and...",
"description": "<p>Easy Chart is a great easy comparison chart maker for math and science skills. It even allows you to pick the appropriate chart type.</p>",
"groups": [
{
"id": 6,
"name": "Fourth Grade (All Subjects)",
"name_short": "4th Grade"
},
{
"id": 17,
"name": "Eighth Grade Science",
"name_short": "8th Science"
},
{
"id": 13,
"name": "Seventh Grade Science",
"name_short": "7th Science"
},
{
"id": 9,
"name": "Sixth Grade Science",
"name_short": "6th Science"
}
],
"tags": [
{
"id": 33,
"tag": "iPad"
},
{
"id": 32,
"tag": "iPod"
}
],
"webpages": [],
"videos": [],
"documents": [],
"photos": [],
"reports": [],
"bookmarks": [],
"likes": [],
"dislikes": [],
"element_type": "Post",
"active": true,
"deleted": false,
"updated_at": "2011-11-27T21:37:38-0600",
"created_at": 1322451458000,
"created_at_formatted": "2 weeks ago"
}'
Search:
$ curl -XPOST 'http://localhost:9200/testindex/element/_search' -d '{
"sort":{ "created_at":{ "order":"desc" } },
"query":{
"constant_score":{
"filter":{
"and":[
{ "missing":{ "field":"parent_id" } },
{ "missing":{ "field":"wall_id" } },
{ "term":{ "active":true } }
]
}
}
},
"facets":{
"tags":{ "terms":{ "field":"tags.tag" } }
}
}'
Result:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "testindex",
"_type": "element",
"_id": "RZK41LngTKOhMUS6DXRi7w",
"_score": null,
"_source": {
"element_id": 4682,
"parent_id": null,
"wall_id": null,
"username": "John Doe",
"avatar": "56f1bb0a96d02b90e5915ff38ea189ec.jpg",
"title": "Easy Chart is a great easy comparison chart maker for math and...",
"description": "<p>Easy Chart is a great easy comparison chart maker for math and science skills. It even allows you to pick the appropriate chart type.</p>",
"groups": [
{
"id": 6,
"name": "Fourth Grade (All Subjects)",
"name_short": "4th Grade"
},
{
"id": 17,
"name": "Eighth Grade Science",
"name_short": "8th Science"
},
{
"id": 13,
"name": "Seventh Grade Science",
"name_short": "7th Science"
},
{
"id": 9,
"name": "Sixth Grade Science",
"name_short": "6th Science"
}
],
"tags": [
{
"id": 33,
"tag": "iPad"
},
{
"id": 32,
"tag": "iPod"
}
],
"webpages": [],
"videos": [],
"documents": [],
"photos": [],
"reports": [],
"bookmarks": [],
"likes": [],
"dislikes": [],
"element_type": "Post",
"active": true,
"deleted": false,
"updated_at": "2011-11-27T21:37:38-0600",
"created_at": 1322451458000,
"created_at_formatted": "2 weeks ago"
},
"sort": [
1322451458000
]
}
]
},
"facets": {
"tags": {
"_type": "terms",
"missing": 0,
"total": 2,
"other": 0,
"terms": [
{
"term": "ipod",
"count": 1
},
{
"term": "ipad",
"count": 1
}
]
}
}
}
(Un)Successful attempt #2:
Create index with mappings:
$ curl -XPOST 'http://localhost:9200/testindex2/' -d '{
"mappings": {
"element": {
"properties": {
"tags": {
"type": "nested",
"include_in_parent": false,
"properties": {
"id": {
"type": "integer"
},
"tag": {
"type": "string"
}
}
}
}
}
}
}'
Index document:
$ curl -XPOST 'http://localhost:9200/testindex2/element' -d '{
"element_id": 4682,
"parent_id": null,
"wall_id": null,
"username": "John Doe",
"avatar": "56f1bb0a96d02b90e5915ff38ea189ec.jpg",
"title": "Easy Chart is a great easy comparison chart maker for math and...",
"description": "<p>Easy Chart is a great easy comparison chart maker for math and science skills. It even allows you to pick the appropriate chart type.</p>",
"groups": [
{
"id": 6,
"name": "Fourth Grade (All Subjects)",
"name_short": "4th Grade"
},
{
"id": 17,
"name": "Eighth Grade Science",
"name_short": "8th Science"
},
{
"id": 13,
"name": "Seventh Grade Science",
"name_short": "7th Science"
},
{
"id": 9,
"name": "Sixth Grade Science",
"name_short": "6th Science"
}
],
"tags": [
{
"id": 33,
"tag": "iPad"
},
{
"id": 32,
"tag": "iPod"
}
],
"webpages": [],
"videos": [],
"documents": [],
"photos": [],
"reports": [],
"bookmarks": [],
"likes": [],
"dislikes": [],
"element_type": "Post",
"active": true,
"deleted": false,
"updated_at": "2011-11-27T21:37:38-0600",
"created_at": 1322451458000,
"created_at_formatted": "2 weeks ago"
}'
Search:
$ curl -XPOST 'http://localhost:9200/testindex2/element/_search' -d '{
"sort":{ "created_at":{ "order":"desc" } },
"query":{
"constant_score":{
"filter":{
"and":[
{ "missing":{ "field":"parent_id" } },
{ "missing":{ "field":"wall_id" } },
{ "term":{ "active":true } }
]
}
}
},
"facets":{
"tags":{ "terms":{ "field":"tags.tag" }, "nested":"tags" }
}
}'
Result:
{
"took": 17,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "testindex2",
"_type": "element",
"_id": "_F1TTGJETOipo8kVR7ZXkQ",
"_score": null,
"_source": {
"element_id": 4682,
"parent_id": null,
"wall_id": null,
"username": "John Doe",
"avatar": "56f1bb0a96d02b90e5915ff38ea189ec.jpg",
"title": "Easy Chart is a great easy comparison chart maker for math and...",
"description": "<p>Easy Chart is a great easy comparison chart maker for math and science skills. It even allows you to pick the appropriate chart type.</p>",
"groups": [
{
"id": 6,
"name": "Fourth Grade (All Subjects)",
"name_short": "4th Grade"
},
{
"id": 17,
"name": "Eighth Grade Science",
"name_short": "8th Science"
},
{
"id": 13,
"name": "Seventh Grade Science",
"name_short": "7th Science"
},
{
"id": 9,
"name": "Sixth Grade Science",
"name_short": "6th Science"
}
],
"tags": [
{
"id": 33,
"tag": "iPad"
},
{
"id": 32,
"tag": "iPod"
}
],
"webpages": [],
"videos": [],
"documents": [],
"photos": [],
"reports": [],
"bookmarks": [],
"likes": [],
"dislikes": [],
"element_type": "Post",
"active": true,
"deleted": false,
"updated_at": "2011-11-27T21:37:38-0600",
"created_at": 1322451458000,
"created_at_formatted": "2 weeks ago"
},
"sort": [
1322451458000
]
}
]
},
"facets": {
"tags": {
"_type": "terms",
"missing": 0,
"total": 2,
"other": 0,
"terms": [
{
"term": "ipod",
"count": 1
},
{
"term": "ipad",
"count": 1
}
]
}
}
}