Elasticsearch Routing allocation awarness and shard allocation - elasticsearch

I have an elasticsearch cluster containing 10 nodes splited across 3 zones (A, B, C).
The ES configuration file contain:
cluster.routing.allocation.awareness.force.zone.values = "A,B,C";
I have a single index (index1) containing =~ 283674 docs with a size of =~ 231MB.
The setting for this index contain:
"number_of_replicas" : "2", "number_of_shards" : "5",
Shards seems correctly distributed across zone but within a single zone they are not evenly distributed (see table below, E.g. Zone C | S = shard, (P = Primary | S = Secondary)
What can I do to correctly distribute my shards?
++------+----------------------------------------------------+
||Zone A-----------------------------------------------------|
|| | ||
|| Node 1| S1 (P) ||
|| +-----------------------------------------------------+ ||
|| | ||
|| | S2 (S) S4 (S) ||
|| | ||
|| Node 2| ||
|| +-----------------------------------------------------+ ||
|| | ||
|| | ||
|| | S0 (S) S3 (S) ||
|| | ||
|| Node 3| ||
|-------+----------------------------------------------------|
||Zone B-----------------------------------------------------|
|| | ||
|| | S0 (P) ||
|| Node 4| ||
|| +-----------------------------------------------------+ ||
|| | ||
|| | ||
|| | S3 (P) S4 (P) ||
|| Node 5| ||
|| +-----------------------------------------------------+ ||
|| | ||
|| | ||
|| | S1 (S) S2 (S) ||
|| Node 6| ||
|-------+----------------------------------------------------|
||Zone C-----------------------------------------------------|
|| | ||
|| | S0 (S) S1 (S) S2 (P) S3 (S) S4 (S) ||
|| Node 7| ||
|| +------------------------------------------------------+ ||
|| | ||
|| | ||
|| | ||
|| Node 8| ||
|| +------------------------------------------------------+ ||
|| | ||
|| | ||
|| | ||
|| Node 9| ||
|| +------------------------------------------------------+ ||
|| | ||
|| | ||
|| - ||
|| Node 10 ||
|------------------------------------------------------------|
+------------------------------------------------------------+

I fixed the issue by forcing the number of shard per host and changing the number of primary / secondary per index:
index.number_of_shards = "5";
index.number_of_replicas = "3";
index.routing.allocation.total_shards_per_node = "2";
This results in 2 shards per node evenly distributed across zone.

Related

represent vertical output horizontally in oracle

my display cade looks like below i want to covert my display from vertical to horizontal
code:-
dbms_output.put_line('output1 : ' || value1);
dbms_output.put_line('output2 : ' || value2);
dbms_output.put_line('output3 : ' || value3);
dbms_output.put_line('output4 : ' || value4);
dbms_output.put_line('output5 : ' || value5);
dbms_output.put_line('output6 : ' || value6);
output:-
output1 : 100
output2 : 200
output3 : 300
output4 : 400
output5 : 500
output6 : 600
I want output like below:-
output1 output2 output3 output4 output5 output6
100 200 300 400 500 600
As a first step, you will need to assign rows to the columns
select output1,output2,....., row_number() over (partition by value1 ,....order by output) col from yourtable
then you add PIVOT:
PIVOT
(
max(output)
for col in (1, 2, 3, ..., 240)
)```
You can use LPAD:
DECLARE
value1 NUMBER(8,2) := 100;
value2 NUMBER(8,2) := 200;
value3 NUMBER(8,2) := 300;
value4 NUMBER(8,2) := 400;
value5 NUMBER(8,2) := 500;
value6 NUMBER(8,2) := 600;
c_width CONSTANT PLS_INTEGER := 10;
BEGIN
dbms_output.put_line(
LPAD('output1', c_width, ' ')
|| ' ' || LPAD('output2', c_width, ' ')
|| ' ' || LPAD('output3', c_width, ' ')
|| ' ' || LPAD('output4', c_width, ' ')
|| ' ' || LPAD('output5', c_width, ' ')
|| ' ' || LPAD('output6', c_width, ' ')
);
dbms_output.put_line(
LPAD(value1, c_width, ' ')
|| ' ' || LPAD(value2, c_width, ' ')
|| ' ' || LPAD(value3, c_width, ' ')
|| ' ' || LPAD(value4, c_width, ' ')
|| ' ' || LPAD(value5, c_width, ' ')
|| ' ' || LPAD(value6, c_width, ' ')
);
END;
/
Which outputs:
output1 output2 output3 output4 output5 output6
100 200 300 400 500 600
or TO_CHAR:
DECLARE
value1 NUMBER(8,2) := 100;
value2 NUMBER(8,2) := 200;
value3 NUMBER(8,2) := 300;
value4 NUMBER(8,2) := 400;
value5 NUMBER(8,2) := 500;
value6 NUMBER(8,2) := 600;
c_width CONSTANT PLS_INTEGER := 10;
c_format CONSTANT VARCHAR2(10) := '999999.99';
BEGIN
dbms_output.put_line(
LPAD('output1', c_width, ' ')
|| ' ' || LPAD('output2', c_width, ' ')
|| ' ' || LPAD('output3', c_width, ' ')
|| ' ' || LPAD('output4', c_width, ' ')
|| ' ' || LPAD('output5', c_width, ' ')
|| ' ' || LPAD('output6', c_width, ' ')
);
dbms_output.put_line(
TO_CHAR(value1, c_format)
|| ' ' || TO_CHAR(value2, c_format)
|| ' ' || TO_CHAR(value3, c_format)
|| ' ' || TO_CHAR(value4, c_format)
|| ' ' || TO_CHAR(value5, c_format)
|| ' ' || TO_CHAR(value6, c_format)
);
END;
/
Which outputs:
output1 output2 output3 output4 output5 output6
100.00 200.00 300.00 400.00 500.00 600.00
db<>fiddle here

I want to write dynamic query from update statement to merge merge statement

I want to write dynamic query from update statement to merge merge statement
'UPDATE ' || T1_TABLENAME || ' t1 ' || 'SET ( ' ||
v_t1_fields || ' ) = (SELECT ' || v_t2_fields || ' FROM ' ||
T2_TEMPTABLE_NAME || ' tmp WHERE ' || v_con || ' ) ' ||
' WHERE EXISTS ( SELECT 1 FROM ' || T2_TEMPTABLE_NAME ||
' tmp WHERE ' || v_con || ' )';
-- HERE v_con = t1.D=t2.D,
v_t1_fields-it can store dynamically-A,B,C
v_t2_fields-it can store dynamically-A,B,C
------------
MERGE INTO TABLE1 t1
USING TABLE2 t2
ON(t1.D=t2.D)
WHEN MATCHED THEN
UPDATE
SET
t1.A=t2.A,
t1.B=t2.B, //update set (t1.A,t1.B,t1.C =t2.A,t2.B,t2.C) not work
t1.C=t2.C;
------------------
'MERGE INTO ' TABLE1 || ' t1 ' ||
' USING ' TABLE2 || ' t2 ' ||
' ON ( ' || v_cons || ' )
when matched then update set ('
|| v_t1_fields || ') = '( || v_t2_fields || ' );' // Its not work--ORA-01747: invalid user.table.column, table.column, or column specification
then i use reg_exp to split the columns
---------------------------
v_Sql := 'MERGE INTO ' TABLE1 || ' t1 ' ||
' USING ' TABLE2 || ' t2 ' ||
' ON ( ' || v_cons || ' )
when matched then update set ('
( ' || regexp_substr(v_t1_fields, '[^,]+', 1, 1) || ' ) = ( ' || regexp_substr(v_t2_fields, '[^,]+', 1, 1) || ' )
( ' || regexp_substr(v_t1_fields, '[^,]+', 1, 2) || ' ) = ( ' || regexp_substr(v_t2_fields, '[^,]+', 1, 2) || ' )
( ' || regexp_substr(v_t1_fields, '[^,]+', 1,3) || ' ) = ( ' || regexp_substr(v_t2_fields, '[^,]+', 1,3) || ' ) ';
this one also not work ----ORA-01747: invalid user.table.column, table.column, or column specification
dynamic update to dynamic merge
while changing merge with update statement
not working
There are few mistakes in concatenation and usage of the MERGE statement.
Try the following dynamic query:
'MERGE INTO '
|| TABLE1
|| ' t1 '
|| ' USING '
|| TABLE2
|| ' t2 '
|| ' ON ( '
|| V_CONS
|| ' ) when matched then update set '
|| REGEXP_SUBSTR(V_T1_FIELDS, '[^,]+', 1, 1)
|| ' = '
|| REGEXP_SUBSTR(V_T2_FIELDS, '[^,]+', 1, 1)
|| ', '
|| REGEXP_SUBSTR(V_T1_FIELDS, '[^,]+', 1, 2)
|| ' = '
|| REGEXP_SUBSTR(V_T2_FIELDS, '[^,]+', 1, 2)
|| ', '
|| REGEXP_SUBSTR(V_T1_FIELDS, '[^,]+', 1, 3)
|| ' = '
|| REGEXP_SUBSTR(V_T2_FIELDS, '[^,]+', 1, 3);
I am assuming that
TABLE1 and TABLE2 are valid table names
V_CONS is a valid condition on tables
V_T1_FIELDS and V_T2_FIELDS contains valid column names of the table
Cheers!!

How to combine multiple row data in a column in select query oracle?

For example:- I have 3 tables .
student :
student_id | name | rollNo | class
1 | a1 | 12 | 5
2 | b1 | 11 | 5
address: there can be multiple address for a user
street | district| country |student_id
gali1 | nanit | india | 1
gali2 | nanital | india | 1
Books : There can be muliple book for the user
book | book_id |student_id
history | 111 | 1
Science | 112 | 1
This is example . I want data to be like this in output .
If i select for student_id 1. Then this would be result
student_id | name | rollNo | class | addresslist | booklist
1 | a1 | 12 | 5 | some sort of | some sort of
| list which | list which
| contain both| contain both
| the address | the book detail
| of user | of user
I am using 12.1 which does not support json for now it is in 12.2 .
addresslist can be like this you can create list as you want but it should have all this data.
[{street:"gali1","distict":"nanital","country":"india","student_id":1},{"street":"gali2","distict":"nanital","country":"india","student_id":1}]
same for booklist
Thanks in advance .
Something like:
WITH json_addresses ( address, student_id ) AS (
SELECT '[' ||
LISTAGG(
'{"street":"' || street || '",'
|| '"district":" || district || '",'
|| '"country":" || country|| '"}',
','
) WITHIN GROUP ( ORDER BY country, district, street )
|| ']',
student_id
FROM address
GROUP BY student_id
),
json_books ( book, student_id ) AS (
SELECT '[' ||
LISTAGG(
'{"book_id":"' || book_id || '",'
|| '"book":" || book || '"}',
','
) WITHIN GROUP ( ORDER BY book, book_id )
|| ']',
student_id
FROM book
GROUP BY student_id
)
SELECT s.*, a.address, b.book
FROM student s
INNER JOIN json_addresses a
ON ( s.student_id = a.student_id )
INNER JOIN json_books b
ON ( s.student_id = b.student_id );

ORA-00920 when running query through UI Framework

My company works with a UI Framework written in PLSQL which interacts with a Java client program.
A lot of queries need to be passed as a VARCHAR2 string to it to be called when needed.
The query
SELECT DISTINCT cod_visum
FROM tbl_visum
WHERE num_firma = 0
AND (code_visum BETWEEN 1 AND 799 OR code_visum BETWEEN 900 AND 999)
AND id_worker IS NULL
OR ( date_valid_to IS NOT NULL
AND p_date_from > NVL (date_valid_to, p_date_from + 1))
ORDER BY 1;
runs fine and returns the expected results when run from the TOAD editor, but when I pass it as a VARCHAR2 to the framework, I keep getting an ORA-00920 (Invalid relational operator) but can't find the cause. (Also the framework catches the exception and only shows me a dialog with the exception number and text >.<)
I've tried several methods of concatinating the variable p_date_from into the VARCHAR2, like
v_sql_norm VARCHAR2 (450)
:= 'SELECT DISTINCT code_visum
FROM tbl_visum
WHERE num_firma = 0
AND (code_visum BETWEEN 1 AND 799 OR code_visum BETWEEN 900 AND 999)
AND id_worker IS NULL
OR ( date_valid_to IS NOT NULL AND '
|| p_date_from
|| ' > NVL(date_valid_to , '
|| (p_date_from + 1)
|| ')) ORDER BY 1';
I already checked the date formats, tried to convert the dates to a string before concatination but everything results in the same exception.
The table used in the query looks like this:
+--------------------+-------+-------------------+
| Column Name | NULL? | DATA TYPE |
+--------------------+-------+-------------------+
| ID_VISUM_ASSIGMENT | N | NUMBER (12) |
| NUM_FIRMA | N | NUMBER (3) |
| CODE_VISUM | N | VARCHAR2 (3 Char) |
| ID_WORKER | Y | NUMBER (10) |
| DATE_VALID_FROM | Y | DATE |
| DATE_VALID_TO | Y | DATE |
+--------------------+-------+-------------------+
Side info: a visum (or visa?) is assigned to a worker starting at a specific date (date_valid_from). It can be assigned to a certain date (date_valid_to), or indefinitely assigned (date_valid_to is NULL).
Thank you in advance, really appreciate any help! :)
edit: yes, cod_visum is a VARCHAR2 but in the query it's used as NUMBER but I also already tried casting it to a number (and mostly it's casted explicitely ^^)
This bit is wrong: the fourth line mixes variable with boilerplate.
OR ( date_valid_to IS NOT NULL AND '
|| p_date_from
|| ' > NVL(date_valid_to , '
|| (p_date_from + 1)
It should be something like
OR ( date_valid_to IS NOT NULL AND '
|| p_date_from
|| ' > NVL(date_valid_to , ('
|| p_date_from
|| ' + 1)'
Also the logic seems wonky, but that's an aside.

Logic: is ( A && !(B || C)) || ( B || C ) the same as ( A || B || C )?

I've encountered some obj-c code and I'm wondering if there's a way to simplify it:
#if ( A && !(B || C)) || ( B || C )
is this the same as?
#if ( A || B || C )
If not, is there another way to formulate it that would be easier to read?
[edit]
I tried the truth table before asking the question, but thought I had to be missing something because I doubted that Foundation.framework/Foundation.h would employ this more complex form. Is there a good reason for it?
Here's the original code (from Foundation.h):
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
Yes. Like others said, you can truth table it. The De Morgan rules can also help.
However, I think the best option is to use a Karnaugh Map. It takes a few minutes to learn, but Karnaugh Maps allow you to consistently find the most minimal expression for boolean logic. Truth tables can verify a minimization, but they can't give it to you.
Here's how I got it:
First, the table layout:
AB
00 01 11 10
0| | | | |
C 1| | | | |
Now, considering your equation, B || C will always cause a truth:
AB
00 01 11 10
0| | T | T | |
C 1| T | T | T | T |
This leaves only two cases. In either case, the right side evaluates to false. For 000, the left side also evaluates to false (0 && !(whatever) is false). For 100, 1 && !(0 ||| 0) evaluates to true. Thus, the statement is true. Filling in:
AB
00 01 11 10
0| F | T | T | T |
C 1| T | T | T | T |
Now, we only need to "cover" all the truths. "C" will cover the bottom row. "B" will cover the middle square (of four values). Thus, "B || C" covers all but the top right square. Now, "A" will cover the right four-space square. It's OK that this is redundant. Thus, "A || B || C" covers all the true squares and omits the only false one.
Get pen + paper + try it, there are only 8 possible inputs
They are the same. You can use Truth Table Generator to test it. Both these expressions give false only in one case, when A, B and C are false.
A | B | C | (B || C) | (!(B || C)) | (A && !(B || C)) | (A && (!(B || C)) || (B || C) | (A || B || C)
------------------------------------------------------------------------------------------------------
T | T | T | T | F | F | T | T
T | T | F | T | F | F | T | T
T | F | T | T | F | F | T | T
T | F | F | F | T | T | T | T
F | T | T | T | F | F | T | T
F | T | F | T | F | F | T | T
F | F | T | T | F | F | T | T
F | F | F | F | T | F | F | F
Based on the last two columns, I would say yes.
Yes it is the same. Using De Morgan rules:
(A && !(B || C)) || (B || C) = (A && !B && !C) || (B || C).
So the second will be true when A = 1 and B, C = 0. If that is not the case the second part (B || C) will be true when B || C. So it is equal to the first.
You could also say :
(A && !(B || C)) || (B || C) rewrites to (A && !W) || W (1)
(1) rewrites to (A && !W) || (A || !A || W) (2)
(2) rewrites (A && !W) || (A || W) || (!A || W) (3)
(3) rewrites (A && !W) || !(A && !W) || (A || W) (4)
(4) leads to A || W and then A || B || C
Yes, the two expressions are equivalent. (I just wrote a couple of functions to test all eight possibilities.)

Resources