如何调试与App Engine文档搜索的所有写入/读取?

时间:2014-12-14 20:04:56

标签: google-app-engine

我的工作是从DataStore接收电子邮件(先前已提取)并将其放入与发送电子邮件时间相对应的搜索索引中。一切顺利,我看到工作正在进行中的结果。但是,一段时间后(这很奇怪!)我看到结果为空。我没有任何代码可以删除结果(不需要)。我该如何进一步调试?是否有关于搜索索引中何时有写操作的统计信息?另外,我可以获得任何索引中的文档总数吗?然后我可以轮询这个号码。以下是将电子邮件放入搜索索引的代码:

def get_index_from_email(cls, user, raw_email_model):
        email_date = raw_email_model.date()
        userDomain = re.search("@[\w.]+", str(user.google_display_email)).group()[1:]
        index_name = (userDomain + ":" +
                      str(email_date.month) + ":" + 
                      str(email_date.day / 7) + ":" +
                      str(email_date.year))
        return search.Index(name=index_name) 

def put_message_into_index(cls, user, raw_email_model):
        d = cls._make_document(user, raw_email_model)
        index = cls.get_index_from_email(user, raw_email_model)
        try:
            index.put(d)
#             if not memcache.get(index.name+"counter"):
#                 memcache.set(key=index.name+"counter", value=0)
#             memcache.incr(index.name+"counter")
            logging.info("Put document %s into index: %s", raw_email_model.messageId, index.name)
        except search.Error:
            logging.error("Error trying to add %s to index %s", str(raw_email_model.messageId), index.name)
        except Exception as e:
            logging.error("Error trying to put message %s into index %s", raw_email_model.messageId, index.name)

编辑:添加_make_document代码:

def _make_document(cls, user, raw_email_model):
        if raw_email_model.is_email():
            fields = [
                      search.TextField(name='from', value=raw_email_model.from_address()),
                      search.DateField(name='sent', value=raw_email_model.date()),
                      search.TextField(name='to', value=raw_email_model.to_address()),
                      search.TextField(name='ccAddr', value=raw_email_model.cc_address()),
                      search.TextField(name='subject', value=raw_email_model.subject()),
                      search.TextField(name='messageId', value=raw_email_model.messageId),
                      search.TextField(name='threadId', value=raw_email_model.threadId),
                      search.TextField(name='content', value=raw_email_model.content()),
                      ]

            return search.Document(doc_id=raw_email_model.messageId, fields = fields)

以及查询结果索引的代码:

for index in domain_indexes:
                    if index:
                        logging.debug("Searching in index %s", str(index.name))
                        search_result_futures += [index.search_async(searchQuery)]
                        num_searches = 0

                searchResults = []
                for future in search_result_futures:
                    searchResults += future.get_result()
                for result in searchResults:
                    responseListItem = {}
                    for field in result.fields:
                        if field.name == "sent":
                            responseListItem["time"] = field.value.isoformat()
                        elif field.name == "content":
                            responseListItem["content"] = TeamInboxSearch.get_snippet(quote(field.value)[0][1], searchQuery)
                        else:
                            responseListItem[field.name] = field.value
                    response.append(responseListItem)
                    num_searches = num_searches + 1

1 个答案:

答案 0 :(得分:0)

您是否在devserver上运行此代码?这对我来说可能是一个愚蠢的问题但是我想确定 - 我认为devserver不尊重搜索数据的持久性,只有数据存储(并且在那时,它可能会偶尔删除数据存储,具体取决于你的工作)。 / p>

我认为您正在错误地形成搜索索引。您要将要搜索的数据放在get_index_from_email中索引的名称中,而不是搜索文档的字段中。我假设您的用例是您希望能够在特定时间范围内搜索来自给定用户的所有电子邮件。您可以将来自每个用户的每封电子邮件放在同一个简单命名的索引中,或者您可以根据用户电子邮件的域名或者用户域和年份的组合等来命名(从而划分)索引......但是您似乎正在为插入的文档所代表的(userDomain, month, day, year)的每个可能元组形成一个新的搜索索引。

这意味着你唯一真正的自由参数是一天中的时间,这对我来说似乎不对。请原谅我,如果这是故意的,你的用例实际上就是这个。只是如果您将数据全部存储在一个索引上,或者只是以更广泛的方式在索引之间划分文档,就可以进行更强大的搜索。您可以在查询中指定月,日,年等...而不是索引名称。正是这种情况让我觉得用于检索文档的代码由于对如何存储文档的误解而失败。

索引的名称应该简单,或者最多应限制在您从用户电子邮件中提取的域中,并且应使用各种cls._make_document()TextField中创建用户电子邮件文档s和DateField表示时间数据。

无论如何,如果这还没有为您解决问题,请回复一下有关您如何运行此代码的详细信息,以及cls._make_document()的代码和您的代码用于尝试查询索引以获取您存储的文档。

在这里查看python的搜索api文档[1]

[1] - https://cloud.google.com/appengine/docs/python/search/