如何在Elasticsearch中高效地搜索嵌套的JSON对象,并只返回相关数据,而不返回整个文档?
我有一个JSON对象,表示每个用户都将摄取的菜单结构。每个菜单项都有嵌套字段,如“文本”、“URL”、“区域”和“子项”。我希望能够搜索这些领域的任何一个,并返回搜索查询的相关数据。例如,如果我搜索“工作流角色”,我只想返回相关的菜单项,而不是所有额外的数据。
我尝试为菜单对象创建嵌套Map,但是我使用内部命中的查询返回了太多的数据。我也尝试过路径过滤器,但没有找到满意的解决方案。
所以我的问题是
1.在Elasticsearch中摄取深度嵌套的JSON对象以实现高效搜索的最佳方法是什么?
1.对于这样一个深度嵌套的对象,Map应该如何构造?
1.如何编写一个查询,使我可以搜索所有嵌套字段,并只返回搜索查询的相关数据?
下面是需要搜索的JSON对象示例:
[
{
"MenuStructure": 0,
"NavigationLinkId": 0,
"Children": [
{
"MenuStructure": 0,
"NavigationLinkId": 111,
"Text": "Bulk Actions",
"Action": "Index",
"Controller": "BulkUpload",
"Area": "Company",
"Url": "/some-url/bulk-upload",
}
]
},
{
"MenuStructure": 1,
"NavigationLinkId": 1,
"Children": [
{
"MenuStructure": 1,
"NavigationLinkId": 2,
"Text": "Company Config",
"Area": "Company",
"Url": "javascript:void(0);",
"Children": [
{
"MenuStructure": 1,
"NavigationLinkId": 0,
"Text": "Basic Settings",
"Url": "javascript:void(0);",
"Children": [
{
"MenuStructure": 1,
"NavigationLinkId": 60668,
"Text": "Company Settings",
"Icon": "fas fa-cogs",
"Url": "javascript:void(0);",
"Children": [
{
"MenuStructure": 1,
"NavigationLinkId": 27,
"Text": "Basic Company Information",
"Icon": "fa fa-building",
"Action": "Index",
"Controller": "CompanyProfile",
"Area": "Company",
"Url": "/some-url/company-profile",
},
{
"MenuStructure": 1,
"NavigationLinkId": 163,
"Text": "Reminder Contact Details",
"Icon": "fas fa-balance-scale-right",
"Url": "/some-url/classic/163",
}
]
},
{
"MenuStructure": 1,
"NavigationLinkId": 0,
"Text": "Dropdown Management",
"Icon": "fas fa-users-class",
"Url": "javascript:void(0);",
"Children": [
{
"MenuStructure": 1,
"NavigationLinkId": 261,
"Text": "Workflow Roles",
"Action": "Index",
"Controller": "CompanyWorkflowRoles",
"Area": "Company",
"Url": "/some-url/workflow-roles"
},
{
"MenuStructure": 1,
"NavigationLinkId": 50323,
"Text": "Other Dropdowns",
"Icon": "fas fa-balance-scale-right",
"Url": "/some-url/classic/50323"
}
]
},
{
"MenuStructure": 1,
"NavigationLinkId": 50327,
"Text": "Legislative Configurations",
"Icon": "fas fa-balance-scale-right",
"Url": "javascript:void(0);",
"Children": [
{
"MenuStructure": 1,
"NavigationLinkId": 244,
"Text": "Statistics SA Config",
"Url": "/some-url/classic/244"
}
]
}
]
},
{
"MenuStructure": 1,
"NavigationLinkId": 167,
"Text": "Security",
"Icon": "fa fa-lock",
"Url": "javascript:void(0);",
"Children": [
{
"MenuStructure": 1,
"NavigationLinkId": 167,
"Text": "Security",
"Icon": "fa fa-lock",
"Url": "javascript:void(0);",
"Children": [
{
"MenuStructure": 1,
"NavigationLinkId": 168,
"Text": "User Profiles",
"Url": "/some-url/classic/168",
},
{
"MenuStructure": 1,
"NavigationLinkId": 169,
"Text": "Security Roles",
"Url": "/some-url/classic/169",
},
{
"MenuStructure": 1,
"NavigationLinkId": 188,
"Text": "User Org. Unit Permissions",
"Url": "/some-url/classic/188",
},
{
"MenuStructure": 1,
"NavigationLinkId": 60610,
"Text": "Activate Users",
"Url": "/some-url/classic/60610",
}
]
}
]
}
]
}
]
}
]
为了实现这一点,我尝试为菜单对象创建一个嵌套的字段类型Map。以下是一个示例Map:
PUT my-index
{
"mappings": {
"properties": {
"user_id": {
"type": "keyword"
},
"menu": {
"type": "nested",
"properties": {
"MenuStructure": {
"type": "long"
},
"NavigationLinkId": {
"type": "long"
},
"Text": {
"type": "text"
},
"Action": {
"type": "keyword"
},
"Controller": {
"type": "keyword"
},
"Area": {
"type": "keyword"
},
"Url": {
"type": "keyword"
},
"Icon": {
"type": "keyword"
},
"Children": {
"type": "nested",
"properties": {
"MenuStructure": {
"type": "long"
},
"NavigationLinkId": {
"type": "long"
},
"Text": {
"type": "text"
},
"Action": {
"type": "keyword"
},
"Controller": {
"type": "keyword"
},
"Area": {
"type": "keyword"
},
"Url": {
"type": "keyword"
},
"Icon": {
"type": "keyword"
},
"Children": {
"type": "nested",
"properties": {
"MenuStructure": {
"type": "long"
},
"NavigationLinkId": {
"type": "long"
},
"Text": {
"type": "text"
},
"Action": {
"type": "keyword"
},
"Controller": {
"type": "keyword"
},
"Area": {
"type": "keyword"
},
"Url": {
"type": "keyword"
},
"Icon": {
"type": "keyword"
},
"Children": {
"type": "nested",
"properties": {
"MenuStructure": {
"type": "long"
},
"NavigationLinkId": {
"type": "long"
},
"Text": {
"type": "text"
},
"Action": {
"type": "keyword"
},
"Controller": {
"type": "keyword"
},
"Area": {
"type": "keyword"
},
"Url": {
"type": "keyword"
},
"Icon": {
"type": "keyword"
},
"Children": {
"type": "nested",
"properties": {
"MenuStructure": {
"type": "long"
},
"NavigationLinkId": {
"type": "long"
},
"Text": {
"type": "text"
},
"Action": {
"type": "keyword"
},
"Controller": {
"type": "keyword"
},
"Area": {
"type": "keyword"
},
"Url": {
"type": "keyword"
},
"Icon": {
"type": "keyword"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
如何搜索任何子节点的嵌套属性,我尝试了以下和其他一些类似的查询类型:
GET my-index/_search
{
"query": {
"nested": {
"path": "menu",
"query": {
"bool": {
"must": [
{"match":
{
"menu.Children.Area": "Company"
}
}
]
}
},
"inner_hits": {"highlight": {"fields": {"menu.Children.Area": {}}}}
}
}
}
上面的查询实际上并不起作用,因为它基本上返回了这么多数据。我只想返回内部点击,例如,如果您搜索'Workflow Roles',则只返回
{
"MenuStructure": 1,
"NavigationLinkId": 261,
"Text": "Workflow Roles",
"Action": "Index",
"Controller": "CompanyWorkflowRoles",
"Area": "Company",
"Url": "/some-url/workflow-roles"
}
而不是所有的额外数据。我已经尝试了相当多的组合与路径过滤器等。但我想我正在走这条路。
1条答案
按热度按时间kxkpmulp1#
您需要多级嵌套字段(
menu
+所有Children
子字段)并相应地设计您的查询,然后它将按照您的期望工作。查询的设计方式需要使每个嵌套字段都需要自己的嵌套查询,因此您可能必须执行以下操作: