def search(request, domain):
    """
    Accepts search criteria as GET params, e.g. "https://www.commcarehq.org/a/domain/phone/search/?a=b&c=d"
    Returns results as a fixture with the same structure as a casedb instance.
    """
    criteria = request.GET.dict()
    try:
        case_type = criteria.pop('case_type')
    except KeyError:
        return HttpResponse('Search request must specify case type',
                            status=400)
    try:
        case_search_criteria = CaseSearchCriteria(domain, case_type, criteria)
        search_es = case_search_criteria.search_es
    except QueryMergeException as e:
        return _handle_query_merge_exception(request, e)
    try:
        hits = search_es.run().raw_hits
    except Exception as e:
        return _handle_es_exception(
            request, e, case_search_criteria.query_addition_debug_details)

    # Even if it's a SQL domain, we just need to render the hits as cases, so CommCareCase.wrap will be fine
    cases = [
        CommCareCase.wrap(flatten_result(result, include_score=True))
        for result in hits
    ]
    fixtures = CaseDBFixture(cases).fixture
    return HttpResponse(fixtures, content_type="text/xml; charset=utf-8")
Beispiel #2
0
def app_aware_search(request, domain, app_id):
    """
    Accepts search criteria as GET params, e.g. "https://www.commcarehq.org/a/domain/phone/search/?a=b&c=d"
    Returns results as a fixture with the same structure as a casedb instance.
    """
    criteria = request.GET.dict()
    try:
        case_type = criteria.pop('case_type')
    except KeyError:
        return HttpResponse('Search request must specify case type', status=400)

    try:
        case_search_criteria = CaseSearchCriteria(domain, case_type, criteria)
    except TooManyRelatedCasesError:
        return HttpResponse(_('Search has too many results. Please try a more specific search.'), status=400)
    search_es = case_search_criteria.search_es

    try:
        hits = search_es.run().raw_hits
    except Exception as e:
        notify_exception(request, str(e), details=dict(
            exception_type=type(e),
        ))
        return HttpResponse(status=500)

    # Even if it's a SQL domain, we just need to render the hits as cases, so CommCareCase.wrap will be fine
    cases = [CommCareCase.wrap(flatten_result(result, include_score=True)) for result in hits]
    if app_id:
        cases.extend(get_related_cases(domain, app_id, case_type, cases))

    fixtures = CaseDBFixture(cases).fixture
    return HttpResponse(fixtures, content_type="text/xml; charset=utf-8")
    def test_add_blacklisted_ids(self):
        criteria = {
            "commcare_blacklisted_owner_ids": "id1 id2 id3,id4"
        }
        expected = {'query':
                    {'filtered':
                     {'filter':
                      {'and': [
                          {'term': {'domain.exact': 'swashbucklers'}},
                          {"term": {"type.exact": "case_type"}},
                          {"term": {"closed": False}},
                          {'not': {'term': {'owner_id': 'id1'}}},
                          {'not': {'term': {'owner_id': 'id2'}}},
                          {'not': {'term': {'owner_id': 'id3,id4'}}},
                          {'match_all': {}}
                      ]},
                      "query": {
                          "match_all": {}
                      }}},
                    'size': CASE_SEARCH_MAX_RESULTS}

        self.checkQuery(
            CaseSearchCriteria(DOMAIN, 'case_type', criteria).search_es,
            expected
        )
Beispiel #4
0
 def test_date_range_criteria(self):
     config, _ = CaseSearchConfig.objects.get_or_create(pk=self.domain,
                                                        enabled=True)
     self._assert_query_runs_correctly(
         self.domain, [
             {
                 '_id': 'c1',
                 'dob': date(2020, 3, 1)
             },
             {
                 '_id': 'c2',
                 'dob': date(2020, 3, 2)
             },
             {
                 '_id': 'c3',
                 'dob': date(2020, 3, 3)
             },
             {
                 '_id': 'c4',
                 'dob': date(2020, 3, 4)
             },
         ],
         CaseSearchCriteria(self.domain, self.case_type, {
             'dob': '__range__2020-03-02__2020-03-03'
         }).search_es, None, ['c2', 'c3'])
     config.delete()
    def test_add_blacklisted_ids(self):
        criteria = {"commcare_blacklisted_owner_ids": "id1 id2 id3,id4"}
        expected = {
            "query": {
                "bool": {
                    "filter": [{
                        'term': {
                            'domain.exact': 'swashbucklers'
                        }
                    }, {
                        "term": {
                            "type.exact": "case_type"
                        }
                    }, {
                        "term": {
                            "closed": False
                        }
                    }, {
                        "bool": {
                            "must_not": {
                                "term": {
                                    "owner_id": "id1"
                                }
                            }
                        }
                    }, {
                        "bool": {
                            "must_not": {
                                "term": {
                                    "owner_id": "id2"
                                }
                            }
                        }
                    }, {
                        "bool": {
                            "must_not": {
                                "term": {
                                    "owner_id": "id3,id4"
                                }
                            }
                        }
                    }, {
                        "match_all": {}
                    }],
                    "must": {
                        "match_all": {}
                    }
                }
            },
            "size": CASE_SEARCH_MAX_RESULTS
        }

        self.checkQuery(
            CaseSearchCriteria(DOMAIN, 'case_type', criteria).search_es,
            expected)
    def test_add_ignore_pattern_queries(self):
        rc = IgnorePatterns(
            domain=DOMAIN,
            case_type='case_type',
            case_property='name',
            regex=' word',
        )  # remove ' word' from the name case property
        rc.save()
        self.config.ignore_patterns.add(rc)
        rc = IgnorePatterns(
            domain=DOMAIN,
            case_type='case_type',
            case_property='name',
            regex=' gone',
        )  # remove ' gone' from the name case property
        rc.save()
        self.config.ignore_patterns.add(rc)
        rc = IgnorePatterns(
            domain=DOMAIN,
            case_type='case_type',
            case_property='special_id',
            regex='-',
        )  # remove '-' from the special id case property
        rc.save()
        self.config.ignore_patterns.add(rc)
        self.config.save()
        rc = IgnorePatterns(
            domain=DOMAIN,
            case_type='case_type',
            case_property='phone_number',
            regex='+',
        )  # remove '+' from the phone_number case property
        rc.save()
        self.config.ignore_patterns.add(rc)
        self.config.save()

        criteria = OrderedDict([
            ('phone_number', '+91999'),
            ('special_id', 'abc-123-546'),
            ('name', "this word should be gone"),
            ('other_name', "this word should not be gone"),
        ])

        expected = {
            "query": {
                "filtered": {
                    "filter": {
                        "and": [{
                            "term": {
                                "domain.exact": "swashbucklers"
                            }
                        }, {
                            "term": {
                                "type.exact": "case_type"
                            }
                        }, {
                            "term": {
                                "closed": False
                            }
                        }, {
                            "match_all": {}
                        }]
                    },
                    "query": {
                        "bool": {
                            "must": [{
                                "nested": {
                                    "path": "case_properties",
                                    "query": {
                                        "filtered": {
                                            "filter": {
                                                "and": ({
                                                    "term": {
                                                        "case_properties.key.exact":
                                                        "phone_number"
                                                    }
                                                }, {
                                                    "term": {
                                                        "case_properties.value.exact":
                                                        "91999"
                                                    }
                                                }),
                                            },
                                            "query": {
                                                "match_all": {}
                                            }
                                        }
                                    }
                                }
                            }, {
                                "nested": {
                                    "path": "case_properties",
                                    "query": {
                                        "filtered": {
                                            "filter": {
                                                "and": ({
                                                    "term": {
                                                        "case_properties.key.exact":
                                                        "special_id"
                                                    }
                                                }, {
                                                    "term": {
                                                        "case_properties.value.exact":
                                                        "abc123546"
                                                    }
                                                })
                                            },
                                            "query": {
                                                "match_all": {}
                                            }
                                        }
                                    }
                                }
                            }, {
                                "nested": {
                                    "path": "case_properties",
                                    "query": {
                                        "filtered": {
                                            "filter": {
                                                "and": ({
                                                    "term": {
                                                        "case_properties.key.exact":
                                                        "name"
                                                    }
                                                }, {
                                                    "term": {
                                                        "case_properties.value.exact":
                                                        "this should be"
                                                    }
                                                })
                                            },
                                            "query": {
                                                "match_all": {}
                                            }
                                        }
                                    }
                                }
                            }, {
                                "nested": {
                                    "path": "case_properties",
                                    "query": {
                                        "filtered": {
                                            "filter": {
                                                "and": ({
                                                    "term": {
                                                        "case_properties.key.exact":
                                                        "other_name"
                                                    }
                                                }, {
                                                    "term": {
                                                        "case_properties.value.exact":
                                                        ("this word should not be gone"
                                                         )
                                                    }
                                                })
                                            },
                                            "query": {
                                                "match_all": {}
                                            }
                                        }
                                    }
                                }
                            }]
                        }
                    }
                }
            },
            "size": CASE_SEARCH_MAX_RESULTS,
        }
        self.checkQuery(
            CaseSearchCriteria(DOMAIN, 'case_type', criteria).search_es,
            expected,
        )