**0**

##### 4 答案

**0**

**My method for simplification:**

*(1) Start with the outermost operator and move it to the start of the expression.*

```
"(A operator B)" becomes "operator (A B)"
```

*(2) Repeat step 1 for each sub expression with an operator to move.*

```
"A operator (B operator C)" becomes "operator A (B operator C)" then "operator A (operator B C)"
```

*(3) Remove all brackets.*

```
"A operator (B operator C)" becomes "operator A operator B C"
```

**So for my example:**

`( A or B ) AND ( C or D or E )`

First simplification:

`AND ( A or B ) ( C or D or E )`

left side

`AND ( or A B ) ( C or D or E )`

right side outer

`AND ( or A B ) ( or C ( D or E ) )`

right side inner

`AND ( or A B ) ( or C ( or D E ) )`

remove brackets

`AND or A B or C or D E`

**In OpenERP domain syntax this would be:**

`[ '&', '|', (A), (B), '|', (C), '|', (D), (E) ] `

**0**

OpenERP uses Polish Notation for Domain filters.

First you should understand what is polish notation. You can find detailed information in wikipedia about polish notation. http://en.wikipedia.org/wiki/Polish_notation

About your question

```
( A OR B ) AND ( C OR D OR E )
```

should converted to the polish notation as

```
AND OR A B OR OR C D E
```

And should be solved by the algorithm with following order [] represents operation

```
AND [OR A B] OR OR C D E Result of [OR A B] is F
AND F OR [OR C D] E Result of [OR C D] is G
AND F [OR G E] Result of [OR G E] is H
[AND F H]
```

it starts from **LEFT** to Right.

"If another operator is found before two operands are found, then the old operator is placed aside until this new operator is resolved. This process iterates until an operator is resolved, which must happen eventually, as there must be one more operand than there are operators in a complete statement." From wikipedia article.

you can also use in operator instead of writing three separate tuples with OR operator like

```
['&',('field2', 'in', ['A', 'B']),('state', 'in', ['open', 'closed', 'draft'])]
```

you can check the various use of the domain filters in the actions list from

Settings > Actions > Window Actions (technical features should be on)

**0**

Your first guess is OK. You may find easyer to understan it if you start with the Reversed Polish Notation, which is a little more intuitive for programmers.

en.wikipedia.org/wiki/Reverse_Polish_notation

There is a good example:

The infix expression "5 + ((1 + 2) * 4) â 3" can be written down like this in RPN:

`5 1 2 + 4 * + 3 -`

The reversed notation is exactly the same, but enables you to resolve without going back and forth.

The infix expression requires you to compute first the inner addition "1 + 2", then multiply by 4, then add 5 and finally add 3, off course you can change some orders and thats one problem.

With reverse polish notation you apply the operators you find to the inmediately preceding operands in the stack, the partial result replace them as a new operand, you follow the same with the next operator, an so on until there's no more operators. In this case: "5 1 2 + 4 * + 3 -" you find + and apply to 1 and 2, replace with the partial result, now your stack is "5 3 4 * + 3 -", find first operator again, *, and apply to two preceding operands, 4 and 3, now you have this stack "5 12 + 3 -", find the next operator, + , and apply to preceding operands, 5 and 12, replace the result in the stack "17 3 -", again, find the firs operator and apply the preceding operands: "14". Done.

In this example you take always two operands because thats that's what apply to the operators, if you find unary operator (a negation for example) you apply to only one preceding operand. You could find an operator which requires 3 or more operands.

In your example, if you reverse and simplify the expression you get this:

E D C | | B A | &

If you resolv this logical expresion with the same algorithm follow in the previous numeric example, you'll find you get exactly what you want.

Thereafter, you only need to acomodate your mind to the non-reversed notation, which is the same, perhaps a little bit less intuitive.

Hope this helps.

Best regards.

**0**

You can also use Python lambda expression to filtered out the record set.

self.env['your.model'].search([]).filtered(lambda x:

(x.field1.id == some_id.id and x.field2.id == False and x.field3.id == some_id.id and x.name == name.strip().upper()) or

(x.field1.id == some_id.id and x.field2.id == some_id.id and x.field3.id == some_id.id and x.name == name.strip().upper())

)

Here we have OR operator between 2 main chunks of filters (which have AND operators)

DO NOTdo what "Sehrish" suggested, unless youknowyou have a good reason to do so. It might be easier than figuring out polish notation, but what you're effectively doing is retrievingallrecords of the given model from the databaseand thenfiltering, which is very likely going to be horrible for performance because unless you have maybe 100 records max, you're going to be pullinga lotof data.