Elasticsearch Nest not honoring index = not_indexed on POCO field? - elasticsearch

i just found out through the documentation that we should be telling it to use the mapping attributes and manually creating the index before we index.
however, the documentation is not consistent with the newest version of the code. (pre release).
http://nest.azurewebsites.net/nest/indices/put-mapping.html
var response = this.ConnectedClient.Map<ElasticSearchProject>();
the call above in the new code takes 1 argument in the Map() method. the documentation is not requiring any arguments.
what should be contained in that method? it seems like there are many options, but i'm unclear on which ones to use.

Have a look at the Create Indices documentation. I think something like this will work for what you are trying to accomplish. Plus it will create the index and apply the mapping all in one call to your Elasticsearch instance.
client.CreateIndex("myindexname", c => c
.NumberOfReplicas(0)
.NumberOfShards(1)
.Settings(s=>s
.Add("merge.policy.merge_factor","10")
.Add("search.slowlog.threshold.fetch.warn", "1s")
)
.AddMapping<ElasticSearchProject>(m => m.MapFromAttributes())
.AddMapping<Person>(m => m.MapFromAttributes())
);
The .AddMapping<ElasticSearchProject>(m => m.MapFromAttributes()) line tells NEST to grab all of the Attribute settings on the via ElasticType and ElasticProperty on the ElasticSearchProject class and use those to create the mapping.

Related

Search multiple indices against some index pattern using NEST

I searched NEST docs but seems to cant find a proper answer for it.
My question is how to search multiple indices against some index pattern using NEST? e.g
if I have indices with following names in Elasticsearch DB
media-2017-10, media-2018-03, media-2018-04
For specifying my selected indices, I need to use wild card character * like this:
client.Search<Media>(s => s
.Index("media-*")
. query goes here .....
Is it possible in NEST ?
Yes, this works. Try it :)
.Index(...) accepts wildcard indices
You can also search in multiple indices in that way:
var allIndices = new[] {
"media-*",
"docs-*",
"common-*"
};
Nest.Indices allIndices = allIndices;
return _elasticClient
.SearchAsync<EsBaseModel>(s => s
.Index( allIndices)
.Size(_esConfig.MaxCallIDsSize)
.RequestConfiguration(r => r.RequestTimeout(TimeSpan.FromMinutes(5)))
.Query(q =>
q.Match(m => m.Field("fieldname").Query(condition))
));
Steps:
Just create an array with string indices.
Indices can be explicit or implicit using any pattern supported in Nest client docs.
Notice - neet to put attention to optimize the searching, since it could take a while to search in all the indices that you've provided.
(optimize can be achieved by ignoring very old dates, limit the results, etc...)

Creating Elasticsearch Index using NEST 5.x

I am trying to create an index using NEST 5.x pre release version for Elasticsearch 5.x. I have samples from 2.x which shows how index can be created using ElasticClient.CreateIndex method. Below is my sample code.
ESnode = new Uri("http://localhost:9200");
Nodesettings = new ConnectionSettings(ESnode);
Client = new ElasticClient(Nodesettings);
However, when I am typing below, there is NO autocomplete available.
Client.CreateIndex( c => c.
I am able to successfully get the health of the node using below code.
var res = Client.ClusterHealth();
Console.WriteLine("Status:" + res.Status);
I am having a complex document mapping for which I have defined the class structure and intend to use Automap method. Hence I am trying to create the index programatically to avoid manually creating the index.
I tried using some very old version of NEST (1.x) and I am able to get the autocomplete for createIndex. But both v2.4x and 5.x did not provide the autocomplete. Is there a new way to create index? Please let me know.
Thanks
You need to supply a name to the index, in addition to the delegate that provides additional index creation options
var createIndexResponse = client.CreateIndex("index-name", c => c
.Settings(s => s
.NumberOfShards(1)
.NumberOfReplicas(0)
)
.Mappings(m => m
.Map<Conference>(d => d
.AutoMap()
)
)
);

Sharing index mapping configuration in NEST 2.3.3?

Upgrading Elastic & NEST search from 1.6.2 to 2.3.3.
We used be able to share the same PutMappingDescriptor between ElasticClient.CreateIndex() and ElasticClient.Map().
But in 2.3.3, the CreateIndex needs TypeMappingDescriptor and Map requires PutMappingDescriptor.
How do we share the same mapping configuration?
The official Nest developers answered this question in their github, linked here.
Basically, you don't use Func<PutMappingDescriptor<Project>, IPutMappingRequest> but PutMappingDescriptor<Project> directly. by newing up a PutMappingDescriptor<Project> and build up your fluent mapping from there.
Creating index expects ITypeMapping while updating index expects IPutMappingRequest which implements ITypeMapping. So you can satisfy both by using PutMappingDescriptor.
To create an index, use:
```
client.CreateIndex("projects", c => c
.Mappings(ms => ms
.Map(m => GetMapping())
)
);
```
where you ignore m passed in in the lambda and use the one you created. The reason why you can do that can be found in NEST's source code where it creates an empty TypeMappingDescriptor for your to further build upon:
public MappingsDescriptor Map<T>(Func<TypeMappingDescriptor<T>, ITypeMapping> selector) where T : class =>
Assign(typeof (T), selector?.Invoke(new TypeMappingDescriptor<T>()));
To update mapping, do:
client.Map(GetMapping());

Elasticsearch - with or without a "doc."?

I'm facing some strange issue with "doc." keyword on Nest C# Elasticsearch.
I'm using Couchbase, and I have a class where one of its fields is an array of objects
I try to search inside this array for a specific value.
Something like this:
string mailFilesKey = string.Empty;
ISearchResponse<object> result = _mainManager.Client.Search<object>(c => c
.Type("MailFiles")
.Query(q =>
q.Term("SentFile_Id", fileId))
.Size(1));
Now, this thing actually works. But when I do this one, it doesn't work:
q.Term("doc.SentFile_Id", fileId))
Why?
haha ok nice one. I had this thing long time ago when i started to use Nest and elastic. If you have the object then you can use lambda expressions
like f=>f.SentFile_Id.
Now when you use a string to get the name of the field in nest you must know that all fields, index name, types in elastic are stored with lowercase first letter. So you should use this : q.Term("sentFile_Id", fileId))
Should work just fine.

Find documents including element in Array field with mongomapper?

I am new to mongodb/mongomapper and can't find an answer to this.
I have a mongomapper class with the following fields
key :author_id, Integer
key :partecipant_ids, Array
Let's say I have a "record" with the following attributes:
{ :author_id => 10, :partecipant_ids => [10,15,201] }
I want to retrieve all the objects where the partecipant with id 15 is involved.
I did not find any mention in the documentation.
The strange thing is that previously I was doing this query
MessageThread.where :partecipant_ids => [15]
which worked, but after (maybe) some change in the gem/mongodb version it stopped working.
Unfortunately I don't know which version of mongodb and mongomapper I was using before.
In the current versions of MongoMapper, this will work:
MessageThread.where(:partecipant_ids => 15)
And this should work as well...
MessageThread.where(:partecipant_ids => [15])
...because plucky autoexpands that to:
MessageThread.where(:partecipant_ids => { :$in => [15] })
(see https://github.com/jnunemaker/plucky/blob/master/lib/plucky/criteria_hash.rb#L121)
I'd say take a look at your data and try out queries in the Mongo console to make sure you have a working query. MongoDB queries translate directly to MM queries except for the above (and a few other minor) caveats. See http://www.mongodb.org/display/DOCS/Querying

Resources