Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specifying .Analyzer in mapping destroys the GeoPoint mapping. #2498

Closed
daluas opened this issue Dec 16, 2016 · 12 comments
Closed

Specifying .Analyzer in mapping destroys the GeoPoint mapping. #2498

daluas opened this issue Dec 16, 2016 · 12 comments

Comments

@daluas
Copy link

daluas commented Dec 16, 2016

NEST/Elasticsearch.Net version: 5.0.0.0

Elasticsearch version:
"version" : {
"number" : "5.1.1",
"build_hash" : "5395e21",
"build_date" : "2016-12-06T12:36:15.409Z",
"build_snapshot" : false,
"lucene_version" : "6.3.0"
}

Description of the problem including expected versus actual behavior:
Specify the .Analyzer property in CreateIndex -> .Mappings section, crete a strange mapping:

"location":{"properties":{"lat":{"type":"float"},"lon":{"type":"float"}}}

If I'm omitting the .Analyzer and let the NEST select its default analyzer, in that case, the GeoPoint filed is correctly mapped as expected: "location":{"type":"geo_point"}

Provide ConnectionSettings (if relevant):

elasticClient.CreateIndex(usersIndex, i => indexDescriptor
.InitializeUsing(indexDescriptor)
.Mappings(ms => ms.Map(m => m.AutoMap()
.Properties(prop => prop.GeoPoint(geo => geo.Name(g => g.Location)))
//.Analyzer("whitespace")
))
);

@gmarz
Copy link
Contributor

gmarz commented Dec 19, 2016

Hi @daluas I'm having trouble trying to reproduce this. Specifying the mapping with and without Analyzer produces the expected results.

In your example snippet I see you're initializing with indexDescriptor, and also building on that rather than i. Is this intentional? If so, can you share a more complete example including the full indexDescriptor?

@daluas
Copy link
Author

daluas commented Dec 20, 2016

Hi,

This is the method that initializes the client:

private const string usersIndex = "users";

private void ConfigureElastiClient()
{
var nodes = new List()
{
new Uri("http://127.0.0.1:9200")
};
var pool = new StaticConnectionPool(nodes);
var config = new ConnectionSettings(pool).DisableDirectStreaming();

        config.DefaultIndex(usersIndex);

        elasticClient = new ElasticClient(config);

        var indexDescriptor = new CreateIndexDescriptor(new IndexName
        {
            Name = usersIndex
        }).Mappings(ms => ms.Map<UserSearchEntity>(m => m.AutoMap()));

        elasticClient.CreateIndex(usersIndex, i => indexDescriptor
            .InitializeUsing(indexDescriptor)
            .Mappings(ms => ms.Map<UserSearchEntity>(m => m.AutoMap()
            .Properties(prop => prop.GeoPoint(geo => geo.Name(g => g.Location)))
            .Analyzer("whitespace")
            ))
        );
    }

I'm using this method to insert users in Elastic Search:

private void AddToElasticSearch(UserSearchEntity line)
{
//elasticClient.Index(line);
elasticClient.Index(line, idx => idx.Index(elasticClient.ConnectionSettings.DefaultIndex));
}

and below is my User class:

public class UserSearchEntity
{
public string Id { get; set; }

    public string Name { get; set; }

    [GeoPoint]
    public GeoLocation Location { get; set; }

    public string LocationAddress { get; set; }
}

Commented out the .Analyzer("whitespace") line in the initialization method is doing the "location":{"type":"geo_point"} mapping. Having this line as uncommented performs "location":{"properties":{"lat":{"type":"float"},"lon":{"type":"float"}}} mapping.

@gmarz
Copy link
Contributor

gmarz commented Dec 20, 2016

@daluas still not able to reproduce this.

What is the value of elasticClient.ConnectionSettings.DefaultIndex? Is it different than userIndex? If so, you are indexing to a different index, which is being created dynamically, rather than the one you're creating explicitly, and thus Location will is getting mapped as an object by default rather than GeoPoint.

Also, I'd like to suggest a few other improvements:

  • IndexName is implicitly convertible from a string, so no need to new IndexName()
  • You don't need to create your index descriptor upfront, you can set your properties on it within the fluent call
  • Related, you are calling .Map() twice on UserSearchEntity
  • Since you've applied the GeoPoint attribute to Location, you don't need to explicitly map it as a GeoPoint, and instead just rely on AutoMap() to pick up on the attribute

Try this instead:

elasticClient.CreateIndex(usersIndex, i => i
    .Mappings(ms => ms
        .Map<UserSearchEntity>(m => m
            .AutoMap()
            .Analyzer("whitespace")
        )
    )
)

Also, as mentioned above, specify userIndex in your index requests rather than the DefaultIndex, unless they are intentionally different...

elasticClient.Index(line, idx => idx.Index(userIndex));

Let me know if that helps.

@daluas
Copy link
Author

daluas commented Dec 21, 2016

Hello,

I tried to do it as you indicated...but...elasticClient.CreateIndex method returns an error:

{Type: mapper_parsing_exception Reason: "Failed to parse mapping [usersearchentity]: Root mapping definition has unsupported parameters: [analyzer : whitespace]" CausedBy: "Type: mapper_parsing_exception Reason: "Root mapping definition has unsupported parameters: [analyzer : whitespace]""}

ElasticSearchTest.zip

As I mentioned: elasticClient.CreateIndex fails with the error...but...elasticClient.Index(line, idx => idx.Index(usersIndex)); is working and creates the mappings I mentioned in this issue.
location":{"properties":{"lat":{"type":"float"},"lon":{"type":"float"}}}

@gmarz
Copy link
Contributor

gmarz commented Dec 21, 2016

Ah, makes sense now :)

The create index request is failing because analyzers are no longer supported at the type level. See elastic/elasticsearch#8874

Unfortunately, we never removed this methods from the client, but I just opened #2506 which marks them obsolete. You should set the whitespace analyzer per field instead, or set it as the default for the index.

Since the index creation was failing, your indexing requests created an index and dynamic mapping on the fly, which defaults Location to an object rather than geo_point. If you fix the above you should be good.

@gmarz gmarz closed this as completed Dec 21, 2016
@daluas
Copy link
Author

daluas commented Dec 22, 2016

Hi,

I've changed my class like this:

public class UserSearchEntity
{
public string Id { get; set; }

    [Text(Analyzer = "whitespace", SearchAnalyzer = "whitespace")]
    public string Name { get; set; }

    [GeoPoint]
    public GeoLocation Location { get; set; }

    public string LocationAddress { get; set; }
}

but the SearchAnalyzer seems to not work.
but searching by Alina-Cristina returns also a user Alina Damian (you can see my users here), which should not be returned if the analyser is whitespace.

Any thoughts about this?

@Mpdreamz
Copy link
Member

@daluas what is the query you use to search for Alina-Cristina ?

@daluas
Copy link
Author

daluas commented Dec 29, 2016

It's fixed now. A colleague of you helped me and indicated that I have to specify the field in order to used the whitespace analyzer...otherwise the _all fields will be used and it uses the simple analyzer.

@ffMathy
Copy link

ffMathy commented Sep 19, 2019

Did you ever solve this?

@daluas
Copy link
Author

daluas commented Sep 19, 2019

Yes. As I indicated, the field used for whitespace analyzer should be specified, otherwise, all fields will be used. When all fields are used, the simple analyzer is in place.

@ffMathy
Copy link

ffMathy commented Sep 19, 2019

Thank you for your reply - but I don't understand what the analyzer has to do with the mapping issue of geo_point. I'm having the same symptom as you, but I can't figure out how to make the changes you are talking about.

Can you provide a pseudo-ish code example?

Thanks in advance.

@daluas
Copy link
Author

daluas commented Sep 19, 2019

Is your problem related to the GeoPoint mappings?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants