def setUp(self):
        # Create ES mapping
        self.es_mapping = ElasticSearchMapping(models.SearchTestChild)

        # Create ES document
        self.obj = models.SearchTestChild(title="Hello", subtitle="World", page_id=1)
        self.obj.save()
        self.obj.tags.add("a tag")
    def setUp(self):
        # Create ES mapping
        self.es_mapping = ElasticSearchMapping(models.SearchTest)

        # Create ES document
        self.obj = models.SearchTest(title="Hello")
        self.obj.save()
        self.obj.tags.add("a tag")
    def setUp(self):
        # Import using a try-catch block to prevent crashes if the elasticsearch-py
        # module is not installed
        try:
            from wagtail.wagtailsearch.backends.elasticsearch import ElasticSearchMapping
            from elasticsearch.serializer import JSONSerializer
        except ImportError:
            raise unittest.SkipTest("elasticsearch-py not installed")

        self.JSONSerializer = JSONSerializer

        # Create ES mapping
        self.es_mapping = ElasticSearchMapping(models.SearchTestChild)

        # Create ES document
        self.obj = models.SearchTestChild(title="Hello", subtitle="World")
        self.obj.save()
    def test_add_model(self):
        self.rebuilder.start()

        # Add model
        self.rebuilder.add_model(models.SearchTest)

        # Check the mapping went into Elasticsearch correctly
        mapping = ElasticSearchMapping(models.SearchTest)
        response = self.es.indices.get_mapping(self.backend.es_index, mapping.get_document_type())

        # Make some minor tweaks to the mapping so it matches what is in ES
        # These are generally minor issues with the way Wagtail is
        # generating the mapping that are being cleaned up by Elasticsearch
        # TODO: Would be nice to fix these
        expected_mapping = mapping.get_mapping()
        expected_mapping['searchtests_searchtest']['properties']['pk']['store'] = True
        expected_mapping['searchtests_searchtest']['properties']['live_filter'].pop('index')
        expected_mapping['searchtests_searchtest']['properties']['live_filter'].pop('include_in_all')
        expected_mapping['searchtests_searchtest']['properties']['published_date_filter']['format'] = \
            'dateOptionalTime'
        expected_mapping['searchtests_searchtest']['properties']['published_date_filter'].pop('index')

        self.assertDictEqual(expected_mapping, response[self.backend.es_index]['mappings'])
Example #5
0
    def related_articles(self):
        if not self.pk:
            # In preview mode
            return []
        max_results = getattr(settings, "MAX_RELATED_RESULTS", 4)
        es_backend = get_search_backend()
        mapping = ElasticSearchMapping(self.__class__)
        search_fields = []
        for ii in self.search_fields:
            if getattr(ii, "boost", None):
                search_fields.append("{0}^{1}".format(ii.field_name, ii.boost))
            else:
                search_fields.append(ii.field_name)
        query = {
            "query": {
                "filtered": {
                    "filter": {
                        "term": {
                            "live_filter": True
                        }
                    },
                    "query": {
                        "more_like_this": {
                            "docs": [{
                                "_id": mapping.get_document_id(self),
                                "_type": mapping.get_document_type()
                            }],
                            "min_doc_freq":
                            1,
                            "min_term_freq":
                            2,
                            "max_query_terms":
                            500,
                            "min_word_length":
                            4,
                            "fields":
                            search_fields
                        }
                    }
                }
            }
        }

        try:
            mlt = es_backend.es.search(index=es_backend.index_name,
                                       doc_type=mapping.get_document_type(),
                                       body=query)
        except ConnectionError:
            return []
        # Get pks from results
        pks = [hit['_source']['pk']
               for hit in mlt['hits']['hits']][:max_results]

        # Initialise results dictionary
        results = dict((str(pk), None) for pk in pks)

        # Find objects in database and add them to dict
        queryset = self._default_manager.filter(pk__in=pks)
        for obj in queryset:
            results[str(obj.pk)] = obj

        # Return results in order given by ElasticSearch
        return [results[str(pk)] for pk in pks if results[str(pk)]]
Example #6
0
    def related_articles(self):
        if not self.pk:
            # In preview mode
            return []

        max_results = getattr(settings, "MAX_RELATED_RESULTS", 4)
        es_backend = get_search_backend()
        mapping = ElasticSearchMapping(self.__class__)

        minimal_locations = ""
        if (self.get_minimal_locations()):
            minimal_locations = self.get_minimal_locations()

        state_locations = ""
        if (self.get_state_from_locations()):
            state_locations = self.get_state_from_locations()

        authors_of_article = ""

        if self.authors:
            for author in self.authors.all():
                authors_of_article += author.name

        query = {
            "track_scores": "true",
            "query": {
                "bool": {
                    "must": [
                        {"match": {"language": self.language}},
                        {"term": {"live_filter": "true"}}
                    ],
                    "must_not": [
                        {"term": {"title_filter": self.title}}

                    ],
                    "should": [
                        {
                            "multi_match": {
                                "fields": "get_authors_or_photographers_filter",
                                "query": ["" + authors_of_article + ""]
                            }

                        },
                        {
                            "multi_match": {
                                "fields": "get_authors",
                                "query": ["" + authors_of_article + ""]
                            }

                        },
                        {
                            "multi_match": {
                                "fields": "get_minimal_locations_filter",
                                "query":minimal_locations
                            }
                        },
                        {
                            "multi_match":{
                                "fields":"get_state_from_locations_filter",
                                "query":state_locations
                            }

                        },
                        {
                            "match":{
                                "title":self.title
                            }
                        }
                    ],
                    "minimum_should_match": 1
                }
            },
            "sort": [
                {"_score": {"order": "desc"}},
                {"get_authors":{"order": "desc"}},
                {"first_published_at_filter": "desc"}
            ]
        }


        try:
            mlt = es_backend.es.search(
                index=es_backend.index_name,
                doc_type=mapping.get_document_type(),
                body=query
            )
        except ConnectionError:
            return []
        # Get pks from results
        pks = [hit['_source']['pk'] for hit in mlt['hits']['hits']][:max_results]

        # Initialise results dictionary
        results = dict((str(pk), None) for pk in pks)

        # Find objects in database and add them to dict
        queryset = self._default_manager.filter(pk__in=pks)
        for obj in queryset:
            results[str(obj.pk)] = obj

        # Return results in order given by ElasticSearch
        return [results[str(pk)] for pk in pks if results[str(pk)]]