How to do mongoid 'not_in' 'greater than' query - ruby

If I want to search a mongoid model with attribute greater than 100 I would do this.
Model.where({'price' => {'$gt' => 100}})
How do I do search a mongoid model without attribute greater than 100?
Tried this and failed.
Model.not_in({'price' => [{'$gt' => 100}]})
Additional info:
In the end of the day would like to make a query like so:
criteria = {
'price' => [{'$gt' => 100}],
'size' => 'large',
'brand' => 'xyz'
}
Model.not_in(criteria)
As the criteria would be dynamically created.

model without attribute greater than 100 = model with attribute less than or equal to 100?
Model.where({'price' => {'$lte' => 100}})

Try this
Model.where(:price.lte => 100,:size.ne => 'large',:brand.ne => 'xzy')

Try using the .ne() (not equals) operator
Model.where({:price.lte => 100}).ne({:size => 'large', :brand => 'xzy'})
You can also find the Mongoid documentation here http://mongoid.org/en/origin/docs/selection.html#negation

Related

Elegantly return value(s) matching criteria from an array of nested hashes - in one line

I have been searching for a solution to this issue for a couple of days now, and I'm hoping someone can help out. Given this data structure:
'foo' => {
'bar' => [
{
'baz' => {'faz' => '1.2.3'},
'name' => 'name1'
},
{
'baz' => {'faz' => '4.5.6'},
'name' => 'name2'
},
{
'baz' => {'faz' => '7.8.9'},
'name' => 'name3'
}
]
}
I need to find the value of 'faz' that begins with a '4.', without using each. I have to use the '4.' value as a key for a hash I will create while looping over 'bar' (which obviously I can't do if I don't yet know the value of '4.'), and I don't want to loop twice.
Ideally, there would be an elegant one-line solution to return the value '4.5.6' to me.
I found this article, but it doesn't address the full complexity of this data structure, and the only answer given for it is too verbose; the looping-twice solution is more readable. I'm using Ruby 2.3 on Rails 4 and don't have the ability to upgrade. Are there any Ruby gurus out there who can guide me?
You can use select to filter results.
data = {'foo' => {'bar' => [{'baz' => {'faz' => '1.2.3'}, 'name' => 'name1'}, {'baz' => {'faz' => '4.5.6'}, 'name' => 'name2'}, {'baz' => {'faz' => '7.8.9'}, 'name' => 'name3'}]}}
data.dig('foo', 'bar').select { |obj| obj.dig('baz', 'faz').slice(0) == '4' }
#=> [{"baz"=>{"faz"=>"4.5.6"}, "name"=>"name2"}]
# or if you prefer the square bracket style
data['foo']['bar'].select { |obj| obj['baz']['faz'][0] == '4' }
The answer assumes that every element inside the bar array has the nested attributes baz -> faz.
If you only expect one result you can use find instead.

ElasticSearch Aggregation Past _source

I am trying to get a list of all possible article groups. My Product array example is like so:
[8] => Array
(
[_index] => product_index
[_type] => product_51_DEU
[_id] => AV7mxnScT3P3M-G9u9aK
[_score] => 1
[_source] => Array
(
[artikelnummer] => G123456
[produktname] => My Cool Name Here
[artikeltext] => BLA
[produktgruppe] => Car Products
[anwendungsbezeichnung] => Wash Products
[lieferant] => Turtle
)
)
My PHP search parameter looks like this:
$mainMenuParams = [
'index' => 'product_index',
'type' => 'product_51_DEU',
'body' => [
'aggs' => [
'_SOURCE' => [
'terms' => [
'field' => '_source.produktgruppe'
]
]
]
]
];
$listProduktGroup = $GLOBALS["client"]->search($mainMenuParams);
I get an answer but there are no aggregations. I have tried many combinations, but none seem to work. Anyone have any idea where this is wrong? I want to see an aggregation with an output of all of the possible [produktgruppe]. There are 10 Groups in all, but it would be nice to see this in the results and then maybe even a count of all products in each group.
If I do the exact same query on "_types" I get accurate results.

Performance - Ruby - Compare large array of hashes (dictionary) to primary hash; update resulting value

I'm attempting to compare my data, which is in the format of an array of hashes, with another large array of hashes (~50K server names and tags) which serves as a dictionary. The dictionary is stripped down to only include the absolutely relevant information.
The code I have works but it is quite slow on this scale and I haven't been able to pinpoint why. I've done verbose printing to isolate the issue to a specific statement (tagged via comments below)--when it is commented out, the code runs ~30x faster.
After reviewing the code extensively, I feel like I'm doing something wrong and perhaps Array#select is not the appropriate method for this task. Thank you so much in advance for your help.
Code:
inventory = File.read('inventory_with_50k_names_and_associate_tag.csv')
# Since my CSV is headerless, I'm forcing manual headers
#dictionary_data = CSV.parse(inventory).map do |name|
Hash[ [:name, :tag].zip(name) ]
end
# ...
# API calls to my app to return an array of hashes is not shown (returns '#app_data')
# ...
#app_data.each do |issue|
# Extract base server name from FQDN (e.g. server_name1.sub.uk => server_name1)
derived_name = issue['name'].split('.').first
# THIS IS THE BLOCK OF CODE that slows down execution 30 fold:
#dictionary_data.select do |src_server|
issue['tag'] = src_server[:tag] if src_server[:asset_name].start_with?(derived_name)
end
end
Sample Data Returned from REST API (#app_data):
#app_data = [{'name' => 'server_name1.sub.emea', 'tag' => 'Europe', 'state' => 'Online'}
{'name' => 'server_name2.sub.us', 'tag' => 'US E.', 'state' => 'Online'}
{'name' => 'server_name3.sub.us', 'tag' => 'US W.', 'state' => 'Failover'}]
Sample Dictionary Hash Content:
#dictionary_data = [{:asset_name => 'server_name1-X98765432', :tag => 'Paris, France'}
{:asset_name => 'server_name2-Y45678920', :tag => 'New York, USA'}
{:asset_name => 'server_name3-Z34534224', :tag => 'Portland, USA'}]
Desired Output:
#app_data = [{'name' => 'server_name1', 'tag' => 'Paris, France', 'state' => 'Up'}
{'name' => 'server_name2', 'tag' => 'New York, USA', 'state' => 'Up'}
{'name' => 'server_name3', 'tag' => 'Portland, USA', 'state' => 'F.O'}]
Assuming "no" on both of my questions in the comments:
#!/usr/bin/env ruby
require 'csv'
#dictionary_data = CSV.open('dict_data.csv') { |csv|
Hash[csv.map { |name, tag| [name[/^.+(?=-\w+$)/], tag] }]
}
#app_data = [{'name' => 'server_name1.sub.emea', 'tag' => 'Europe', 'state' => 'Online'},
{'name' => 'server_name2.sub.us', 'tag' => 'US E.', 'state' => 'Online'},
{'name' => 'server_name3.sub.us', 'tag' => 'US W.', 'state' => 'Failover'}]
STATE_MAP = {
'Online' => 'Up',
'Failover' => 'F.O.'
}
#app_data = #app_data.map do |server|
name = server['name'][/^[^.]+/]
{
'name' => name,
'tag' => #dictionary_data[name],
'state' => STATE_MAP[server['state']],
}
end
p #app_data
# => [{"name"=>"server_name1", "tag"=>"Paris, France", "state"=>"Up"},
# {"name"=>"server_name2", "tag"=>"New York, USA", "state"=>"Up"},
# {"name"=>"server_name3", "tag"=>"Portland, USA", "state"=>"F.O."}]
EDIT: I find it more convenient here to read the CSV without headers, as I don't want it to generate an array of hashes. But to read a headerless CSV as if it had headers, you don't need to touch the data itself, as Ruby's CSV is quite powerful:
CSV.read('dict_data.csv', headers: %i(name tag)).map(&:to_hash)

How to collect such info in magento listing page?

I need the catalog_product_entity_media_gallery table value data only on listing page.
When i am going to listing page and use the print_r($_productCollection);
$_productCollection on listing page returns me a array like this.
[_resourceName:protected] => catalog/product
[_resource:protected] =>
[_resourceCollectionName:protected] => catalog/product_collection
[_dataSaveAllowed:protected] => 1
[_isObjectNew:protected] =>
[_data:protected] => Array
(
[entity_id] => 160
[entity_type_id] => 4
[attribute_set_id] => 4
[type_id] => simple
[sku] => 104580
[has_options] => 0
[required_options] => 0
[created_at] => 2014-12-01 10:40:25
[updated_at] => 2014-12-01 11:51:15
[cat_index_position] => 1
[price] => 4.4900
[tax_class_id] => 4
[final_price] => 4.4900
[minimal_price] => 4.4900
[min_price] => 4.4900
[max_price] => 4.4900
[tier_price] =>
[name] => E Shisha E Liquid eKaiser *Menthol Flavour* 10ml Platinum Bottle Refill for Rechargeable E cigarette and E Shisha
[msrp_enabled] => 1
[msrp_display_actual_price_type] => 1
[thumbnail] => amazon_images/104580.jpg
[small_image] => amazon_images/104580.jpg
[image_label] =>
[small_image_label] =>
[thumbnail_label] =>
[url_key] => e-shisha-e-liquid-ekaiser-menthol-flavour-10ml-platinum-bottle-refill-for-rechargeable-e-cigarette-and-e-shisha
[short_description] => The eKaiser Platinum e Liquid range is made specifically for Cigarette smokers.
I need the only [small_image] value, which returns me only the amazon_images/104580.jpg
If any One have any idea, how to do it
Please help me.
Thank you
And also you can do like this :
$product = Mage::getModel('catalog/product')->load($_product->getId());
foreach ($product->getMediaGallery('images') as $image) {
...
}
You can do like this on listing page.
$product = Mage::getModel('catalog/product')->load($_product->getId());
foreach ($product->getMediaGalleryImages() as $image) {
var_dump($image->getUrl());
}
A for loop in listing with getModel will slow down your listing page considerably.
With listing page you should only use flat tables for collection.
So you need to make sure that small image is populated in flat table.

How can I get the total number of documents found using the Nest?

I do the same request using the nest, and directly in ElastichSearch.
When I see direct request, how many documents match request.
"hits":
{
"total": 1640,
"max_score": 1,
"hits": [...]
}
My query:
var search = client.Search<RCompany>(s => s.Index("MyIndex")
.Query(qq => qq
.Filtered(m => m.Filter(f => f.Bool(b => b
.Must(
a => a.Term(z => z.Company.Code, param1),
a => a.Terms(z => z.Company.Id, param2),
a => a.Terms(z => z.Company.Field1.Id, param3)
)))
.Query(b => b.Bool(q => q.Should
(n => n.Match(a => a.OnField(d => d.Company.Field2).Query(param5).Operator(Operator.And)),
n => n.Match(a => a.OnField(d => d.Company.Field3).Query(param5).Operator(Operator.And)),
n => n.Match(a => a.OnField(d => d.Company.Field4).Query(param5).Operator(Operator.And)),
n => n.Match(a => a.OnField(d => d.Company.Field5).Query(param5).Operator(Operator.And))
)))))
.Size(10)
.SortDescending(n => n.DtCreate));
How can I find out how many documents suitable request using Nest?
There is a Total property on ISearchResponse which holds the total number of documents that matched the query. In your example, that would be search.Total.
The best way is to use the method Count as proposed by the official documentation
here the code
var result = client.Count<ElasticsearchProject>();

Resources