问题描述
以下是我的索引中单个记录的数据样本:
{
"_index" : "test_index","_type" : "_doc","_id" : "49605102905391763685971719283371021096086998966740189186","_score" : 2.8858113,"_source" : {
"properties" : {
"activity" : [
{
"activityId" : 39,"actionVersion" : 2,"actionIdx" : 3
},{
"activityId" : 39,"actionIdx" : 4
},"actionIdx" : 5
},{
"activityId" : 42,"actionIdx" : 5
}
]
}
}
}
我想基于activitiyId 42和actionIdx 3过滤结果。我正在使用下面的查询尝试获取结果。
{"size":-1,"query": {
"bool": {
"should": {
"bool": {
"must": [
{
"match": {
"activityId": 42
}
},{
"match": {
"actionIdx": 3
}
}
]
}
}
}
}
}
我要获取包含activityid 42和actionidx 3的记录,但我的要求是在同一对象中拥有包含activity 42和actionidx 3的记录。以下是我的上述搜索查询结果:
"activity" : [
{
"activityId" : 39,"actionIdx" : 2
},{
"activityId" : 28,{
"activityId" : 41,"actionIdx" : 3
}
]
我的预期输出是:
"activity" : [
{
"activityId" : 39,"actionIdx" : 3
}
]
这里是映射索引。活动未嵌套
"properties" : {
"properties" : {
"activity" : {
"properties" : {
"actionIdx" : {
"type" : "long"
},"actionVersion" : {
"type" : "long"
},"activityId" : {
"type" : "long"
}
}
}
}
}
解决方法
您需要使用nested data type并进行查询以实现该目标,因为您现在不使用它,它被视为对象数据类型(默认),并且嵌套文档清楚地提到了您所面临的问题。
在摄取具有大型任意键集的键值对时, 您可以考虑将每个键值对建模为自己的嵌套 具有键和值字段的文档。相反,请考虑使用 展平的数据类型,它将整个对象映射为单个字段,并且 允许简单搜索其内容。嵌套文档和 查询通常很昂贵,因此将扁平化数据类型用于 这种用例是一个更好的选择。
索引映射
{
"mappings": {
"properties": {
"properties": {
"properties": {
"activity": {
"type": "nested"
}
}
}
}
}
}
索引数据:
{
"properties": {
"activity": [
{
"activityId": 39,"actionVersion": 2,"actionIdx": 3
},{
"activityId": 39,"actionIdx": 4
},"actionIdx": 5
},{
"activityId": 42,"actionIdx": 5
}
]
}
}
搜索查询:
{
"query": {
"nested": {
"path": "properties.activity","query": {
"bool": {
"must": [
{
"match": {
"properties.activity.activityId": 42
}
},{
"match": {
"properties.activity.actionIdx": 3
}
}
]
}
},"inner_hits":{}
}
}
}
搜索结果
"hits": [
{
"_index": "fd_cb1","_type": "_doc","_id": "1","_nested": {
"field": "properties.activity","offset": 3
},"_score": 2.0,"_source": {
"activityId": 42,"actionIdx": 3
}
}
]