1

I have two indices with the following configuration with mappings

var settings = new ConnectionSettings(new Uri("http://localhost:9200/"));
settings
      .DefaultMappingFor<ManagementIndex>(m => m
          .IndexName("management")
      )
      .DefaultMappingFor<PropertyIndex>(m => m
          .IndexName("apartmentproperty")
      );
var client = new ElasticClient(settings);


1) Properties mapping

client.Indices.Create("property", i => i
                .Settings(s => s
                    .NumberOfShards(2)
                    .NumberOfReplicas(0)
                )
                .Map<PropertyIndex>(map => map
                    .AutoMap()
                    .Properties(p => p
                        .Nested<PropertyData>(n => n
                            .Name(c => c.property)
                            .AutoMap()
                            .Properties(pp => pp
                                .Text(c => c
                                    .Name(np => np.city)
                                    .Analyzer("standard")
                                )
                                .Text(c => c
                                    .Name(np => np.market)
                                    .Fields(ff => ff
                                        .Text(tt => tt
                                            .Name(np => np.market)
                                            .Analyzer("standard")
                                        )
                                        .Keyword(k => k
                                            .Name("keyword")
                                            .IgnoreAbove(256)
                                        )
                                    )
                                ).Text(c => c
                                    .Name(np => np.name)
                                    .Analyzer("standard")
                                )

                            )
                        )
                    )
                )
            );

and

2) Owner

if (client.Indices.Exists("owner").Exists)
                client.Indices.Delete("owner");

            client.Indices.Create("owner", i => i
                .Settings(s => s
                    .NumberOfShards(2)
                    .NumberOfReplicas(0)
                )
                .Map<OwnerIndex>(map => map
                    .AutoMap()
                    .Properties(p => p
                        .Nested<OwnerProp>(n => n
                            .Name(c => c.owner)
                            .AutoMap()
                            .Properties(pp => pp
                                .Text(c => c
                                    .Name(np => np.market)
                                    .Fields(ff => ff
                                        .Text(tt => tt
                                            .Name(np => np.market)
                                            .Analyzer("standard")
                                        )
                                        .Keyword(k => k
                                            .Name("keyword")
                                            .IgnoreAbove(256)
                                        )
                                    )
                                ).Text(c => c
                                    .Name(np => np.name)
                                    .Analyzer("standard")
                                )
                            )
                        )
                    )
                )
            );

with the following POCO definitions

    public class PropertyData
    {
        public string name { get; set; }
        public string city { get; set; }
        public string market { get; set; }
    }

    public class PropertyIndex
    {
        public PropertyData property { get; set; }
    }

    public class OwnerProp
    {
        public string name { get; set; }
        public string market { get; set; }
    }

    public class OwnerIndex
    {
        public OwnerProp owner { get; set; }
    }


Trying to do a search through the two indices like so

 public async Task<object> SearchPropertiesAsync(string searchQuery, List<string> description, int limit = 25, int skip = 1)
        {
            var propertyfilters = new List<Func<QueryContainerDescriptor<object>, QueryContainer>>();
            var ownerFilters = new List<Func<QueryContainerDescriptor<object>, QueryContainer>>();
            if (description.Any())
            {
                propertyfilters.Add(fq => fq.Terms(t => t.Field("property.market.keyword").Terms(description)));
                ownerFilters.Add(fq => fq.Terms(t => t.Field("owner.market.keyword").Terms(description)));
            }

            var searchResponse = await _elasticClient.SearchAsync<object>(s => s
                .Index(Indices.Index(typeof(PropertyIndex)).And(typeof(OwnerIndex)))

                .Query(q => (q
                    .Nested(n => n

                    .Path(Infer.Field<PropertyIndex>(ff => ff.property))

                    .Query(nq => nq

                    .MultiMatch(m => m

                        .Fields(f => f
                            .Field(Infer.Field<PropertyIndex>(ff => ff.property.city))
                            .Field(Infer.Field<PropertyIndex>(ff => ff.property.market))
                            .Field(Infer.Field<PropertyIndex>(ff => ff.property.name))
                        )
                        .Operator(Operator.Or)
                        .Query(searchQuery)
                        .Fuzziness(Fuzziness.Auto)
                    )  && +q.Bool(bq => bq.Filter(propertyfilters))
                        ))
                    ) || (q
                    .Nested(n => n
                    .Path(Infer.Field<OwnerIndex>(ff => ff.mgmt))
                    .Query(nq => nq

                    .MultiMatch(m => m
                        .Fields(f => f
                            .Field(Infer.Field<OwnerIndex>(ff => ff.owner.market))
                            .Field(Infer.Field<OwnerIndex>(ff => ff.owner.name))
                        )
                        .Operator(Operator.Or)
                        .Query(searchQuery)
                        .Fuzziness(Fuzziness.Auto)
                    ) 
                    && +q.Bool(bq => bq.Filter(ownerFilters))
                    ))
                    )
                ).From((skip - 1) * limit)
                    .Size(limit)
            );

            return searchResponse.Documents;
        }

calling the SearchPropertiesAsync method returns this error messages (truncated for brevity)

         ....
          "index": "owner",
          "caused_by": {
            "type": "illegal_state_exception",
            "reason": "[nested] failed to find nested object under path [property]"
          }

         ....
          "index": "property",
          "caused_by": {
            "type": "illegal_state_exception",
            "reason": "[nested] failed to find nested object under path [owner]"
          }

Notice that it looks like its trying to perform a nested search of owner. on property index and a nested search of property. on owner index which doesnt exist.

I feel like this should be a very trivial problem but I have been using ElasticSearch for only 4days now and still very new into it.

Is there something I am doing wrongly or is there something I am missing. Have searched the whole internet to even arrive at the solution I have at the moment.

Note that when you executed the nested query only one index at a time, the code works fine but trying to execute on multiple Indices is where my problem lies. Any help will be highly appreciated.

I am using ElasticSearch 7.3.2 and Nest Client 7.3.0.

I don't mind downgrading to a lower version that works.

4

1 回答 1

0

显然,根据文档

ignore_unmapped (可选,布尔值)指示是否忽略未映射的路径并且不返回任何文档而不是错误。默认为假。

如果为 false,则如果路径是未映射的字段,则 Elasticsearch 会返回错误。

您可以使用该参数查询可能不包含字段路径的多个索引。

因此.IgnoreUnmapped(true),为每个嵌套查询链接查询主体解决了这个问题。以防万一其他人遇到同样的问题

于 2019-10-11T13:30:15.300 回答