setting values of one map to other depending on a condition - groovy

I have couple of records rec1 and rec2.
Both are having a common key/value name1.
when the name1 is equal in both the records then I need to set few values of rec2 to rec1.
I put them into two different loops as below
rec1.each{r1-> each
rec2.each{r2-> each
if(r2.name1 == r1.name1){
r1.name2 = r2.name2
r1.name3 = r2.name3
}
}
}
Is there any better way of doing this
Example : (sorry I am just pasting the contents)
recoRecord : [["CHANNEL":INBOUND, "STOCK_LEVEL":2410.0,
"OFFER_TARIFF_ID":FBUN-MVP-VME-VIRGIN-31-24-04, "P_BAND":P4-6,
"CONTRACT_LENGTH":24.0, "INCENTIVE_POINTS":10.0,
"HANDSET_PKEY_ID":SAM-STD-I9300-1, "CUST_TYPE":MEDIA]]
records : [["MEDIA_SUBSIDY_VALUE":0.0, "CREDIT_CLASS":C5,
"DOM_OTHER_MARGIN":0.0, "isBatchTerminator":false,
"CALL_GROUP_DESC":COMBINED, "DM":20.0, "BLACKBERRY_IND":N,
"PREFERRED_BLACKBERRY":N, "ERROR_ID":0, "CUST_TYPE":MEDIA,
"TARIFF_MRC":30.99, "MOST_USED_TAC":35961404, "FORM_FACTOR":null,
"CAMERA_IND":null, "NEW_MARGIN":22.272501, "MODEL":null,
"IS_MMS_ALLOWANCE":N, "ACTIVE_HANDSET_BANDS":,
"CUST_OUT_OF_ALLOWANCE_PLAN":JV15, "OOB_DOM_VOICE":0.0,
"OOB_DOM_SMS":0.0, "VM_CUST_FLAG":Y, "IB_DATA":0.0,
"CHANNEL_FLAG":INBOUND, "SMS_ALLOWANCE":5000.0, "ROAM_SMS_MARGIN":0.0,
"TARIFF_DESC":30.99 Virgin Media 24 month+1GB 1300mins,
"MARGIN_CHANGE_PCT":0.12691319, "OFFER_VOICE_ALLOWANCE":600,
"MAKE":null, "IS_ONNET_ALLOWANCE":Y, "OFFER_CONTRACT_TERM":24.0,
"PREFERRED_MINUTES":1300, "PREFERRED_ON_NET":Y,
"MOST_USED_IMEI":359614048625860, "DISCOUNT":3.0,
"NetPresentValue":1.15, "RecInd":1, "WIFI_IND":null, "IPHONE_IND":N,
"OFFER_TARIFF_ID":FBUN-MVP-VME-VIRGIN-31-24-04,
"IncentivePoints":-1.0]
when OFFER_TARIFF_ID in both the records are same then I would like to set few values of first record to second record

You do not need to iterate over both the maps. Just need to check the value of that particular key matches or not.
if(r2.'OFFER_TARIFF_ID' == r1.'OFFER_TARIFF_ID'){
//push the required entries from r1 to r2
}
Although in your edit, I do not see a valid data structure for records, I considered r1 and r2 as Maps.

Related

Cosmos DB paginated query with custom order by clause

I want to do a select query in Cosmos DB that returns a maximum number of results (say 50) and then gives me the continuation token so I can continue the search where I left off.
Now let's say my query has 2 equality conditions in my where clause, e.g.
where prop1 = "a" and prop2 = "w" and prop3 = "g"
In the results that are returned, I want the records that satisfy prop1 = "a" to appear first, followed by the results that have prop2 = "w" followed by the ones with prop3 = "g".
Why do I need it? Because while I could just get all the data to my application and sort it there, I can't pull all records obviously as that would mean pulling in too much data. So if I can't order it this way in cosmos itself, in the results that I get, I might only have those records that don't have prop1 = "a" at all. Now I could keep retrying this till I get the ones with prop1 = "a" (I need this because I want to show the results with prop1 = "a" as the first set of results to the user) but I might have to pull like a 100 times to get the first record since I have a huge dataset sitting in my Cosmos DB.
How can I handle this scenario in Cosmos? Thanks!
So if I am understanding your question correctly, you want to accomplish this:
SELECT * FROM c
WHERE
c.prop1 = 'a'
AND
c.prop2 = 'b'
AND
c.prop3 = 'c'
ORDER BY
c.prop1, c.prop2, c.prop3
OFFSET 0 LIMIT 25
Now, luckily you can now do this in CosmosDB SQL. But, there is a caveat. You have to set up a composite index in your collection to allow for this.
So, for this collection, my composite index would look like this:
Now, if I wanted to change it to this:
SELECT * FROM c
WHERE
c.prop1 = 'a'
AND
c.prop2 = 'b'
AND
c.prop3 = 'c'
ORDER BY
c.prop1 DESC, c.prop2, c.prop3
OFFSET 0 LIMIT 25
I could add another composite index to cover that use-case. You can see in your settings it's an array of arrays so you can add as many combinations as you'd like.
This should get you to where you need to be if I understood your question correctly.

Can I filter multiple collections?

I want to filter multiple collections, to return only documents who have those requirements, the problem is when there is more than one matching value in one collection, the elements shown are repeated.
FOR TurmaA IN TurmaA
FOR TurmaB IN TurmaB
FILTER TurmaA.Disciplinas.Mat >10
FILTER TurmaB.Disciplinas.Mat >10
RETURN {TurmaA,TurmaB}
Screenshot of the problem
What your query does is to iterate over all documents of the first collection, and for each record it iterates over the second collection. The applied filters reduce the number of results, but this is not how you should go about it as it is highly inefficient.
Do you actually want to return the union of the matches from both collections?
(SELECT ... UNION SELECT ... in SQL).
What you get with your current approach are all possible combinations of the documents from both collections. I believe what you want is:
LET a = (FOR t IN TurmaA FILTER t.Disciplinas.Mat > 10 RETURN t)
LET b = (FOR t IN TurmaB FILTER t.Disciplinas.Mat > 10 RETURN t)
FOR doc IN UNION(a, b)
RETURN doc
Both collections are filtered individually in sub-queries, then the results are combined and returned.
Another solution would be to store all documents in one collection Turma and have another attribute e.g. Type with a value of "A" or "B". Then the query would be as simple as:
FOR t IN Turma
FILTER t.Disciplinas.Mat > 10
RETURN t
If you want to return TurmaA documents only, you would do:
FOR t IN Turma
FILTER t.Disciplinas.Mat > 10 AND t.Type == "A"
RETURN t
BTW. I recommend to call variables different from collection names, e.g. t instead of Turma if there is a collection Turma.

BatchScanner with limits per range

Is there a way to get first n whole rows using BatchScanner for each range.
I would like to pull latest user activity for multiple users up to say 100 whole rows per user. Row key starts with user id followed with timestamp.
Thanks,
Dejan
Dejan -- Take a look at the WholeRowIterator. Here's some example code for how you would use it.
Connector conn = getConnector();
BatchScanner bs = conn.createBatchScanner("mytable", new Authorizations(), 4);
IteratorSetting iterator = new IteratorSetting(100, WholeRowIterator.class);
bs.addScanIterator(iterator);
for (Entry<Key,Value> entry : bs) {
SortedMap<Key,Value> row = WholeRowIterator.decodeRow(entry.getKey(), entry.getValue());
}

ColdFusion: Object with duplicate values (removing duplicates)

I have a query object (SQL) with some records, the problem is that some of the records contain duplicate values. :( (I can't use DISTINCT in my SQL Query, so how to remove in my object?)
categories[1].id = 1
categories[2].id = 1
categories[3].id = 2
categories[4].id = 3
categories[5].id = 2
Now I want to get a list with 1, 2, 3
Is that possible?
I'm not quite sure why you say you can't use DISTINCT, even given the qualification you offered. It doesn't matter were a query came from (<cfquery>, <cfldap>, <cfdirectory>, built by hand) by the time it's exposed to your CFML code, it's just "a query", so you can definitely use DISTINCT on it:
<cfquery name="distinctCategories" dbtype="query">
SELECT DISTINCT id
FROM categories
</cfquery>

Creating an associative array using a while loop for select list?

I am dynamically generating a selectlist in Drupal and I want to create an associative array to populate the node ID as the value, and the title of the node as the option.
By default, it makes the value for each option the index of the select list. This is no good because the select list is dynamic, meaning the values won't be in the same order.
I used drupal_map_assoc to make the value the same as the option, but I have queries based on the value stored in this field, so if someone updates the value stored, the queries won't match.
<option value="Addison Reserve Country Club Inc.">Addison Reserve Country Club Inc.</option>
I want to replace the value with the Node ID also pulled with the query.
$sql = 'SELECT DISTINCT title, nid FROM {node} WHERE type = \'accounts\' ';
$result = db_query($sql);
while ($row = db_fetch_array($result)) {
$return[] = $row['title'];
//Trying to do something like 'Addison Reserve Country Club' => '2033' - where 2033 is the nid
}
$return = drupal_map_assoc($return);
I think you just want to do this inside the loop:
$return[$row['nid']] = $row['title'];
Based on your comment, you would also want to do an array_flip() right after the loop, but I think your comment may just have it backwards.

Resources