FieldIndexOption 不适用于嵌套对象

FieldIndexOption not applied to nested objects

我正在使用 ElasticSearch 和 NEST 版本 2 来索引数据。我的数据对象可以有相同类型的子对象。我正在使用注释来指示不分析某些字段。发生的事情是这个注释被应用到父对象,而不是子对象。我正在尝试弄清楚如何修改我的注释以包含子实例。

我有这样的东西:

public class Person {
    public int Id {get; set;}

    [String(Index = FieldIndexOption.NotAnalyzed)]
    public string Code {get; set;}

    public Person child {get; set;}
}

我第一次创建索引时如下:

client.Map<Person>(d => d.AutoMap());

映射如下所示:

"people": {
    "mappings": {
        "person": {
            "properties": {
                "id": {
                    "type": "integer"
                },
                "code": {
                    "type": "string",
                    "index": "not_analyzed"
                },
                "child": {
                    "type": "object"
                }
            }
        }
    }
}

我对一些文档进行索引后如下:

client.Index(person);

映射更改为:

"people": {
    "mappings": {
        "person": {
            "properties": {
                "id": {
                    "type": "integer"
                },
                "code": {
                    "type": "string",
                    "index": "not_analyzed"
                },
                "child": {
                    "properties": {
                        "id": {
                            "type": "integer"
                        },
                        "code": {
                            "type": "string"
                        }
                    }
                }
            }
        }
    }
}

假设我有这样一个文档:

{
    "id": 100,
    "code": "ABC100",
    "child": {
        "id": 123,
        "code": "ABC123"
    }
}

顶层person的Code字段没有分析出来,这很好,所以我可以这样搜索:

GET people/_search
{
  "query": {
    "term": {
      "code": "ABC100"
    }
  }
}

但是child上的code字段是用默认的分析器分析的,所以abc123就变成了abc123。

因此,所有这些都会找到我的文档:

GET people/_search
{
  "query": {
    "term": {
      "child.id": 123
    }
  }
}
GET people/_search
{
  "query": {
    "term": {
      "child.code": "abc123"
    }
  }
}
GET people/_search
{
  "query": {
    "match": {
      "child.id": "ABC123"
    }
  }
}

但这不是:

GET people/_search
{
  "query": {
    "term": {
      "child.code": "ABC123"
    }
  }
}

我需要对我的对象注释进行哪些更改才能将相同的字段选项应用于子人物? (顺便说一句,在现实生活中我有几个领域没有分析,还有几个深度。)

Automapping in NEST does not recurse further than the top level by default,因此 Person 上的子 属性 被映射为对象,动态映射和字段类型推断在映射中创建 child 上的字段当您索引文档时。

NEST 可以通过将深度参数传递给 .AutoMap(int)

来递归映射类型
client.Map<Person>(m => m.AutoMap(1));

这将导致以下映射

{
  "properties": {
    "id": {
      "type": "integer"
    },
    "code": {
      "type": "string",
      "index": "not_analyzed"
    },
    "child": {
      "properties": {
        "id": {
          "type": "integer"
        },
        "code": {
          "type": "string",
          "index": "not_analyzed"
        },
        "child": {
          "properties": {},
          "type": "object"
        }
      },
      "type": "object"
    }
  }
}

我们现在使用预期的字段映射设置将 idcode 映射到子对象上。我们还在 child 上得到一个 child 字段,映射为 object.

如果你知道深度永远只会是 1,如果我们不想要顶层 child 上的 child 字段,我们可以稍微整理一下映射,通过使用流畅的映射

client.Map<Person>(m => m
    .AutoMap()
    .Properties(p => p
        .Object<Person>(o => o
            .Name(n => n.child)
            .Properties(pp => pp
                .Number(n => n
                    .Name(nn => nn.Id)
                    .Type(NumberType.Integer)
                )
                .String(s => s
                    .Name(n => n.Code)
                    .NotAnalyzed()
                )
            )
        )
    )
);

产生

{
  "properties": {
    "id": {
      "type": "integer"
    },
    "code": {
      "type": "string",
      "index": "not_analyzed"
    },
    "child": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "code": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    }
  }
}