Loading Parent and Child - elasticsearch

Good day:
I"m trying to accomplish loading parent and children in one go. My query is this:
ISearchResponse<Models.Facilities.Facility> response = await this._elasticClient.SearchAsync<Models.Facilities.Facility>(s =>
s.Query(q => (q.GeoDistance(g => g.Boost(1.1)
.Field(f => f.BusinessLocation)
.DistanceType(GeoDistanceType.Arc)
.Distance(search.location.distance.ToString() + "m")
.Location((double)search.location.latitude, (double)search.location.longitude)
)
&&
q.HasChild<Models.Facilities.FacilityType>(c => c.Query(qq => qq.MatchAll()).Name("FacilityType")))
||
q.GeoDistance(g => g.Boost(1.1)
.Field(f => f.ServiceAreas)
.DistanceType(GeoDistanceType.Arc)
.Distance(search.location.distance.ToString() + "m")
.Location((double)search.location.latitude, (double)search.location.longitude))
)
.Aggregations(a =>
a.Children<Models.Facilities.FacilityType>("Capacity", child => child.Aggregations(ca => ca.Histogram("Capacity",
h => h.Field(p => p.Capacity)
.Interval(10)
.Missing(0))))
.Histogram("Distance", d => d.Field(f => f.BusinessLocation)
.Interval(10)
.Order(HistogramOrder.CountDescending)))
.Sort(g => g.GeoDistance(g => g.Field(f => f.BusinessLocation)
.DistanceType(GeoDistanceType.Arc)
.Order(SortOrder.Descending)
.Unit(DistanceUnit.Miles)).GeoDistance(g => g.Field(f => f.ServiceAreas)
.DistanceType(GeoDistanceType.Arc)
.Order(SortOrder.Descending))));
Facility and FacilityType extends from a parent Document. I'm trying to load the parent Facility along with its children FacilityType. Essentially if I could achieve an object like this facilityObj.facilityTypes. Let me know if this is possible.

InnerHits works for both Nested and Parent/Child relationships.

Related

Async way of implementing search query in Elastic Search Nest Client .NET

I have implemented a Search Query through NEST client and was able to get the records. The code is as follows.
var response = clientProvider.Client.Search<ProjectModel>(s => s
.Index("project_index")
.Type("projects")
.Source(so => so.Excludes(f => f.Field(x => x.FileInfo.FileBase64Data)))
.Size(100)
.Query(q => q
.Bool(b => b
.Should(
m => m.QueryString(qs => qs
.Query(searchOptions.SearchTerm)
.Fields(ff => ff.Fields(fields))
.Fuzziness(Fuzziness.Auto)
),
m => m.MultiMatch(qs => qs
.Query(searchOptions.SearchTerm)
.Type(Nest.TextQueryType.PhrasePrefix)
.Fields(ff => ff.Fields(fields))
)
)
)
)
.Sort(ss => ss.Descending(SortSpecialField.Score))
);
And I am mapping the response to my Project Model as follows.
var project = response.Hits.Select(h =>
{
h.Source._id = h.Id;
h.Source.Score = h.Score;
return h.Source;
}).ToList();
When I am trying to implement the same Search in Async way that is
var response = clientProvider.Client.SearchAsync<ProjectModel>(s => s
.Index("project_index")
.Type("projects")
.Source(so => so.Excludes(f => f.Field(x => x.FileInfo.FileBase64Data)))
.Size(100)
.Query(q => q
.Bool(b => b
.Should(
m => m.QueryString(qs => qs
.Query(searchOptions.SearchTerm)
.Fields(ff => ff.Fields(fields))
.Fuzziness(Fuzziness.Auto)
),
m => m.MultiMatch(qs => qs
.Query(searchOptions.SearchTerm)
.Type(Nest.TextQueryType.PhrasePrefix)
.Fields(ff => ff.Fields(fields))
)
)
)
)
.Sort(ss => ss.Descending(SortSpecialField.Score))
);
I am not getting any errors while executing it. But I am not able to get the response.Hits objects to map it back to my original Project Model.
Thanks In advance
In SearchAsync<T>(), response is Task<ISearchResponse<T>>, so you probably want to await it
Map all documents, found in products index, onto ProductDto type:
var result = await _elasticClient.SearchAsync<ProductDto>(x => x.Index("products").MatchAll());
var documents = result.Documents;

Edit Form in Laravel: Creates New Entry instead of Updating Old Data

I tried to create edit method on form data submission, but instead of updating the old entry, it creates a new entry in the database.
My source files are:
web.php
Route::get('/input_gedung_bangunan/{id_bangunan}', 'input_gedung_bangunan#tampiledit');
Route::post('/data_gedung_bangunan/hitung_data', 'input_gedung_bangunan#store');
Controller:
public function store(Request $request){
//DB::enableQueryLog();
//$id_bangunan = $id;
$validation = \App\Tbl_uraian_datas::where('id_bangunan', '=', $request->get('id_bangunan'))->first();
if(is_null($validation)){
$tbl_uraian_datas = new \App\Tbl_uraian_datas;
$tbl_uraian_datas->id_bangunan = $request->get('id_bangunan');
$tbl_uraian_datas->id_kanwil = Input::get('IDKanwil');
$tbl_uraian_datas->id_kota_kab = Input::get('IDKotaKab');
$tbl_uraian_datas->nomor_baris = Input::get('NomorBaris');
$tbl_uraian_datas->nama_bangunan = Input::get('NamaBangunan');
$tbl_uraian_datas->alamat_bangunan = Input::get('AlamatBangunan');
$tbl_uraian_datas->nama_kota_kab = Input::get('Kota/Kabupaten');
$tbl_uraian_datas->kode_barang = Input::get('KodeBarang');
$tbl_uraian_datas->nup_barang = Input::get('NUPBarang');
$tbl_uraian_datas->luas_lantai = Input::get('LuasLantai');
$tbl_uraian_datas->jumlah_lantai = Input::get('JumlahLantai');
$tbl_uraian_datas->tahun_penilaian = Input::get('TahunPenilaian');
$tbl_uraian_datas->tahun_dibangun = Input::get('TahunDibangun');
$tbl_uraian_datas->tahun_direnovasi = Input::get('TahunDirenovasi');
$tbl_uraian_datas->id_jenis_bangunan = Input::get('IDJenisBangunan');
$tbl_uraian_datas->jenis_bangunan = Input::get('JenisBangunan');
$tbl_uraian_datas->id_kategori = Input::get('IDKategoriBangunan');
$tbl_uraian_datas->kategori_bangunan = Input::get('KategoriBangunan');
$tbl_uraian_datas->id_kondisi = Input::get('IDKondisiBangunan');
$tbl_uraian_datas->kondisi_bangunan = Input::get('KondisiBangunan');
$tbl_uraian_datas->luas_carport = Input::get('LuasCarport');
$tbl_uraian_datas->panjang_pagar_material1 = Input::get('PanjangPagar1');
$tbl_uraian_datas->panjang_pagar_material2 = Input::get('PanjangPagar2');
$tbl_uraian_datas->panjang_pagar_material3 = Input::get('PanjangPagar3');
$tbl_uraian_datas->harga_per_m2 = Input::get('Hargaperm2');
$tbl_uraian_datas->alasan_fisik = Input::get('Alasan1');
$tbl_uraian_datas->penyusutan = Input::get('Penyusutan');
$tbl_uraian_datas->alasan_penyusutan = Input::get('Alasan2');
$tbl_uraian_datas->save();
}else{
//Edit Data Gedung/Bangunan
$tbl_uraian_datas = \App\Tbl_uraian_datas::update(['id_kanwil' => Input::get('IDKanwil'), 'id_kota_kab' => Input::get('IDKotaKab'), 'nomor_baris' => Input::get('NomorBaris'),'nama_bangunan' => Input::get('nama_bangunan'),'alamat_bangunan' => Input::get('AlamatBangunan'),'nama_kota_kab' => Input::get('Kota/Kabupaten'),'kode_barang' => Input::get('KodeBarang'),'nup_barang' => Input::get('NUPBarang'),'luas_lantai' => Input::get('LuasLantai'),'jumlah_lantai' => Input::get('JumlahLantai'),'tahun_penilaian' => Input::get('TahunPenilaian'),'tahun_dibangun' => Input::get('TahunDibangun'),'tahun_direnovasi' => Input::get('TahunDirenovasi'),'id_jenis_bangunan' => Input::get('IDJenisBangunan'),'jenis_bangunan' => Input::get('JenisBangunan'),'id_kategori' => Input::get('IDKategoriBangunan'),'kategori_bangunan' => Input::get('KategoriBangunan'),'id_kondisi' => Input::get('IDKondisiBangunan'),'kondisi_bangunan' => Input::get('KondisiBangunan'),'luas_carport' => Input::get('LuasCarport'),'panjang_pagar_material1' => Input::get('PanjangPagar1'),'panjang_pagar_material2' => Input::get('PanjangPagar2'),'panjang_pagar_material3' => Input::get('PanjangPagar3'),'harga_per_m2' => Input::get('Hargaperm2'),'alasan_fisik' => Input::get('Alasan1'),'penyusutan' => Input::get('Penyusutan'),'alasan_penyusutan' => Input::get('Alasan2')]);
//$tbl_hasil_perhitungans = \App\Tbl_hasil_perhitungans::where('id_bangunan', '=',$request->get('id_bangunan'))->update(['umur_efektif_bangunan' => Input::get('nUmurEfektifBangunan'), 'pembulatan' => Input::get('nPembulatan')]);
$request->session()->flash('alert-success', 'Data Gedung Bangunan was successfully added!');
return back();
}
}
It looks like the controller keeps making the new id for the editted data and I don't know what I did wrong in my controller.
Instead of the following lines in your code:
$validation = \App\Tbl_uraian_datas::where('id_bangunan', '=', $request->get('id_bangunan'))->first();
if(is_null($validation)){
Try this:
$validation = \App\Tbl_uraian_datas::where('id_bangunan', $request->input('id_bangunan'))->first();
if(empty($validation)){
AND
instead of
$tbl_uraian_datas = \App\Tbl_uraian_datas::update(['id_kanwil' => Input::get('IDKanwil'), 'id_kota_kab' => Input::get('IDKotaKab'), 'nomor_baris' => Input::get('NomorBaris'),'nama_bangunan' => Input::get('nama_bangunan'),'alamat_bangunan' => Input::get('AlamatBangunan'),'nama_kota_kab' => Input::get('Kota/Kabupaten'),'kode_barang' => Input::get('KodeBarang'),'nup_barang' => Input::get('NUPBarang'),'luas_lantai' => Input::get('LuasLantai'),'jumlah_lantai' => Input::get('JumlahLantai'),'tahun_penilaian' => Input::get('TahunPenilaian'),'tahun_dibangun' => Input::get('TahunDibangun'),'tahun_direnovasi' => Input::get('TahunDirenovasi'),'id_jenis_bangunan' => Input::get('IDJenisBangunan'),'jenis_bangunan' => Input::get('JenisBangunan'),'id_kategori' => Input::get('IDKategoriBangunan'),'kategori_bangunan' => Input::get('KategoriBangunan'),'id_kondisi' => Input::get('IDKondisiBangunan'),'kondisi_bangunan' => Input::get('KondisiBangunan'),'luas_carport' => Input::get('LuasCarport'),'panjang_pagar_material1' => Input::get('PanjangPagar1'),'panjang_pagar_material2' => Input::get('PanjangPagar2'),'panjang_pagar_material3' => Input::get('PanjangPagar3'),'harga_per_m2' => Input::get('Hargaperm2'),'alasan_fisik' => Input::get('Alasan1'),'penyusutan' => Input::get('Penyusutan'),'alasan_penyusutan' => Input::get('Alasan2')]);
Try:
$tbl_uraian_datas = \App\Tbl_uraian_datas::where('id_bangunan',$request->input('id_bangunan'))->update(['id_kanwil' => Input::get('IDKanwil'), 'id_kota_kab' => Input::get('IDKotaKab'), 'nomor_baris' => Input::get('NomorBaris'),'nama_bangunan' => Input::get('nama_bangunan'),'alamat_bangunan' => Input::get('AlamatBangunan'),'nama_kota_kab' => Input::get('Kota/Kabupaten'),'kode_barang' => Input::get('KodeBarang'),'nup_barang' => Input::get('NUPBarang'),'luas_lantai' => Input::get('LuasLantai'),'jumlah_lantai' => Input::get('JumlahLantai'),'tahun_penilaian' => Input::get('TahunPenilaian'),'tahun_dibangun' => Input::get('TahunDibangun'),'tahun_direnovasi' => Input::get('TahunDirenovasi'),'id_jenis_bangunan' => Input::get('IDJenisBangunan'),'jenis_bangunan' => Input::get('JenisBangunan'),'id_kategori' => Input::get('IDKategoriBangunan'),'kategori_bangunan' => Input::get('KategoriBangunan'),'id_kondisi' => Input::get('IDKondisiBangunan'),'kondisi_bangunan' => Input::get('KondisiBangunan'),'luas_carport' => Input::get('LuasCarport'),'panjang_pagar_material1' => Input::get('PanjangPagar1'),'panjang_pagar_material2' => Input::get('PanjangPagar2'),'panjang_pagar_material3' => Input::get('PanjangPagar3'),'harga_per_m2' => Input::get('Hargaperm2'),'alasan_fisik' => Input::get('Alasan1'),'penyusutan' => Input::get('Penyusutan'),'alasan_penyusutan' => Input::get('Alasan2')]);
You need to tell which row to actually update by giving a where clause

Nest CopyTo, Tokenizer and Analyzer in 2.x

In an older version of Nest I was able to do this:
var newIndexRequest = client.CreateIndex(ci => ci.Index(IndexName.ToLower())
.Analysis(a => a
.Analyzers(an => an
.Add("search_ngram_analyzer", customAnalyzer))
.Tokenizers(t => t
.Add("search_ngram_tokenizer", new NGramTokenizer
{
MaxGram = 500, // qty of chars to separate into tokens
MinGram = 2
})))
.AddMapping<Models.CustomerSearchResult>(m => m
.MapFromAttributes()
.Properties(p => p
.String(s => s.Name("short_name").CopyTo("search").Index(FieldIndexOption.NotAnalyzed))
.String(s => s.Name("legacy_name").CopyTo("search").Index(FieldIndexOption.NotAnalyzed))
.String(s => s.Name("legacy_contact_name").CopyTo("search").Index(FieldIndexOption.NotAnalyzed))
.String(s => s.Name("search").Index(FieldIndexOption.Analyzed).Analyzer("search_ngram_analyzer"))
)
));
Since the documentation hasn't been updated (or I haven't been able to find it), I can't figure out how to do the same thing in Nest 2.x.)
.. I know I need to use AutoMap instead of MapFromAttributes, but don't know how to properly set the Analyzer, Tokenizer, and CopyTo function.
This is all I have so far:
var customerSearchIdxDesc = new CreateIndexDescriptor(Constants.ElasticSearch.CustomerSearchIndexName)
.Mappings(ms => ms.Map<SO.Services.Data.ServiceModel.DtoTypes.Customer.SearchResult>(m => m.AutoMap()));
var response = client.CreateIndex(customerSearchIdxDesc);
Update
Getting closer I think :/
var customerSearchIdxDesc = new CreateIndexDescriptor(Constants.ElasticSearch.CustomerSearchIndexName)
.Settings((f) =>
{
return f.Analysis(analysis => analysis
.Analyzers(analyzers => analyzers
.Custom("search_ngram_analyzer", a => a
.Filters("lowercase")
.Tokenizer("search_ngram_tokenizer")))
.Tokenizers(tokenizers => tokenizers
.NGram("search_ngram_tokenizer", t => t
.MinGram(2)
.MaxGram(500)
.TokenChars(TokenChar.Digit, TokenChar.Letter, TokenChar.Punctuation, TokenChar.Punctuation, TokenChar.Symbol))));
})
.Mappings(ms => ms.Map<SO.Services.Data.ServiceModel.DtoTypes.Customer.SearchResult>(m => m.AutoMap()));
This is my solution
var customerSearchIdxDesc = new CreateIndexDescriptor(Constants.ElasticSearch.CustomerSearchIndexName)
.Settings(f =>
f.Analysis(analysis => analysis
.Analyzers(analyzers => analyzers
.Custom(Constants.ElasticSearch.AnalyzerNames.LowercaseNGram, a => a
.Filters("lowercase")
.Tokenizer(Constants.ElasticSearch.TokenizerNames.NoWhitespaceNGram)))
.Tokenizers(tokenizers => tokenizers
.NGram(Constants.ElasticSearch.TokenizerNames.NoWhitespaceNGram, t => t
.MinGram(2)
.MaxGram(500)
.TokenChars(TokenChar.Digit, TokenChar.Letter, TokenChar.Punctuation, TokenChar.Punctuation, TokenChar.Symbol)
)
)
)
)
.Mappings(ms => ms.Map<ServiceModel.DtoTypes.Customer.SearchResult>(m => m
.AutoMap()
.Properties(p => p
.String(n => n.Name(c => c.CustomerName).CopyTo(f =>
{
return new FieldsDescriptor<string>().Field("search");
}).Index(FieldIndexOption.Analyzed).Analyzer(Constants.ElasticSearch.AnalyzerNames.LowercaseNGram))
.String(n => n.Name(c => c.ContactName).CopyTo(fs => fs.Field(Constants.ElasticSearch.CombinedSearchFieldName)).Index(FieldIndexOption.Analyzed).Analyzer(Constants.ElasticSearch.AnalyzerNames.LowercaseNGram))
.String(n => n.Name(c => c.City).CopyTo(fs => fs.Field(Constants.ElasticSearch.CombinedSearchFieldName)).Index(FieldIndexOption.Analyzed).Analyzer(Constants.ElasticSearch.AnalyzerNames.LowercaseNGram))
.String(n => n.Name(c => c.StateAbbreviation).CopyTo(fs => fs.Field(Constants.ElasticSearch.CombinedSearchFieldName)).Index(FieldIndexOption.Analyzed).Analyzer(Constants.ElasticSearch.AnalyzerNames.LowercaseNGram))
.String(n => n.Name(c => c.Country).CopyTo(fs => fs.Field(Constants.ElasticSearch.CombinedSearchFieldName)).Index(FieldIndexOption.Analyzed).Analyzer(Constants.ElasticSearch.AnalyzerNames.LowercaseNGram))
.String(n => n.Name(c => c.PostalCode).CopyTo(fs => fs.Field(Constants.ElasticSearch.CombinedSearchFieldName)).Index(FieldIndexOption.Analyzed).Analyzer(Constants.ElasticSearch.AnalyzerNames.LowercaseNGram))
.String(n => n.Name(Constants.ElasticSearch.CombinedSearchFieldName).Index(FieldIndexOption.Analyzed).Analyzer(Constants.ElasticSearch.AnalyzerNames.LowercaseNGram))
)
)
);
var response = client.CreateIndex(customerSearchIdxDesc);

How to Get Model Values in DataCellTemplate() of Kendo-PivotGrid-MVC

#(Html.Kendo().PivotGrid<Models.MyModel>()
.Name("pivotgrid")
.DataSource(dataSource => dataSource.Ajax()
.Transport(transport => transport.Read("ActionMethod", "Controller"))
.Schema(schema => schema.Cube(cube => cube.Dimensions(dimensions =>
{
dimensions.Add(model => model.FirstName).Caption("Learner");
dimensions.Add(model => model.CompetencyCode).Caption("Competency Codes");
dimensions.Add(model => model.OutComeRTOCode).Caption("OutCome RTO");
dimensions.Add(model => model.StudentId);
dimensions.Add(model => model.GroupId);
dimensions.Add(model => model.CompetencyId);
})
.Measures(measures => measures.Add("OutComeRTOCode Count").Field(model => model.OutComeRTOCode).AggregateName("Count").Field(a => a.StudentId).Field(a => a.GroupId).Field(a => a.EnrolmentId).ToString())
))
.Columns(columns => { columns.Add("CompetencyCode").Expand(true); })
.Rows(rows => rows.Add("FirstName").Expand(true))
.Rows(rows => rows.Add("StudentId"))
.Rows(rows => rows.Add("GroupId"))
.Rows(rows => rows.Add("CompetencyId"))
.Measures(measures => measures.Values("OutComeRTOCode Count")))
.DataCellTemplate("<a onclick='GroupEnrolment(StudentId)'>#:kendo.toString(dataItem.value)#</a>")
)
Here in the code ,i am trying to get the StudentId in DataCellTemplate('<'a onclick='GroupEnrolment(Want to Pass StudentId as Parameter here )'>'#:kendo.toString(dataItem.value)#'<'/a'>').
And trying to Pass StudentId in GroupEnrollment(StudentId) as argument, i don't know how to get StudentId from Model and pass it to function-GroupEnrollment in anchor tag.
Or is there any other way to create a link in cells of the Kendo Pivot Grid.
Any help will be appreciated.
Thanks in Advance .

sorting and filtering not working in custom admin module

I am trying to implement an admin module in magento which has a grid in the first page and grids in the tabs while editing the grid entities.
The main grid works fine, but the grids in the tabs are not working fine.
The problem I found while I debugged the code is that, I am loading the collection in the grid with field filtering, ie I am filtering the collection with filter that is the user id. I did this because I need only data of a single user from the table. This made the entire problem, the data in the grid is coming correctly, but the filtering,sorting and searching feature inside grid is not working and returning a 404 not found error page. I tried removing the field filter I added while getting the collection, then it works fine but all the data in the table is coming which is the opposite to my requirement.
Is there any possible solution to this. Here is the way I am trying to do:
protected function _prepareCollection() {
$collection = Mage::getModel('merchant/subscriptions')->getCollection()->addFieldToFilter('user_id', Mage::registry('merchant_data')->getId());
$this->setCollection($collection); //Set the collection
return parent::_prepareCollection();
}
Thanks in advance.
ok My problem is solved there is a mistake in my code. In the grid file the function below was wrong.
public function getGridUrl() {
return $this->getUrl('*/*/transactiongrid', array('user_id',Mage::registry('merchant_data')->getId(), '_current' => true));
}
The correct method was
public function getGridUrl() {
return $this->getUrl('*/*/transactiongrid', array('user_id'=> Mage::registry('merchant_data')->getId(), '_current' => true));
}
Filter action is dependent on your below method:
public function getGridUrl() {
return $this->getUrl('*/*/grid', array('user_id' => Mage::registry('merchant_data')->getId(),'_current'=>true));
}
now this is how you will prepare collection:
protected function _prepareCollection()
{
$regData = Mage::registry('merchant_data');
if(isset($regData))
$regData = $regData->getId();
else
$regData = $this->getRequest()->getParam('user_id');
$collection = Mage::getModel('merchant/subscriptions')->getCollection()->addFieldToFilter('user_id',$regData);
...
When I dumped $regData I got this:
Cubet_Merchant_Model_Merchant Object
(
[_eventPrefix:protected] => core_abstract
[_eventObject:protected] => object
[_resourceName:protected] => merchant/merchant
[_resource:protected] =>
[_resourceCollectionName:protected] => merchant/merchant_collection
[_cacheTag:protected] =>
[_dataSaveAllowed:protected] => 1
[_isObjectNew:protected] =>
[_data:protected] => Array
(
[user_id] => 3
[firstname] => Robin
[lastname] => Cubet
[email] => robin#cubettech.com
[username] => robincubet
[password] => 51a7f45eb11fc49b5967a0039193c3ad:HSX8JkSO5lr3uaRHrzd86i7gb0RATeDb
[created] => 2013-12-12 08:34:28
[modified] => 2013-12-16 09:03:56
[logdate] =>
[lognum] => 0
[reload_acl_flag] => 1
[is_active] => 1
[extra] => N;
[rp_token] =>
[rp_token_created_at] =>
)
[_hasDataChanges:protected] =>
[_origData:protected] => Array
(
[user_id] => 3
[firstname] => Robin
[lastname] => Cubet
[email] => robin#cubettech.com
[username] => robincubet
[password] => 51a7f45eb11fc49b5967a0039193c3ad:HSX8JkSO5lr3uaRHrzd86i7gb0RATeDb
[created] => 2013-12-12 08:34:28
[modified] => 2013-12-16 09:03:56
[logdate] =>
[lognum] => 0
[reload_acl_flag] => 1
[is_active] => 1
[extra] => N;
[rp_token] =>
[rp_token_created_at] =>
)
[_idFieldName:protected] => user_id
[_isDeleted:protected] =>
[_oldFieldsMap:protected] => Array
(
)
[_syncFieldsMap:protected] => Array
(
)
)

Resources