【问题标题】:How to implement Django like 'contains' filter query with Google App Engine?如何使用 Google App Engine 实现 Django 之类的“包含”过滤器查询?
【发布时间】:2010-07-22 12:40:25
【问题描述】:

是否也有一些方法可以使用 Google App Engine 来实现 Django 之类的 contains 或 icontains 过滤器?我正在使用应用引擎补丁。

我之前使用以下查询来匹配字符串的开头,但现在需要在 Datastore 中查找字符串模式。

Employee.all().filter('name >=',value).filter('name <',unicode(value) + u'\ufffd')

基本上,要求是实现一个搜索功能,所有包含搜索字符串的字符串作为结果。

请提出建议。

提前致谢。

【问题讨论】:

    标签: python google-app-engine


    【解决方案1】:

    您需要做的是创建一个具有不同字符串排列的字符串列表属性并在该列表上查询。

    查看 appengine.ext.search.SearchableModel 以获取示例实现。 您也可以查看nonrel-search

    【讨论】:

    • 完美,这就是我想要的。谢谢伊兰。
    • nonrel-search 是否提供开箱即用的“包含”过滤功能?到目前为止我发现的都是startswith
    【解决方案2】:

    不,真正的子字符串搜索在数据存储中是不可能的。

    您可以做的最好的事情是添加一个关键字索引并从您的问题中执行“开始于”类型查询,但即使这样,对于像“foo bar baz”这样的实体,您也可以在搜索“ba " 但不是 "ar b"。

    这对于BigQuery 来说听起来不错,目前正在预览中,并有等待名单来获得访问权限。

    【讨论】:

    • BigQuery 设计用于离线分析处理,而非全文搜索。
    • 感谢您的回复。您能否详细说明或提供您提到的示例代码。在我当前的代码中,“foo bar baz”仅在我搜索“foo”时才会出现在结果中,即字符串本身的开头并且不会搜索“bar”或“baz”。
    • 我也在尝试使用 whoosh,但如果我只输入一个字符进行搜索,它会给出一个“NoneType”对象没有属性“doc_scores”错误消息。
    【解决方案3】:

    最近我遇到了同样的问题,并使用了一个也理解 __contains 的重写过滤器函数创建了自己的模型管理器。我假设你正在使用 Django。

    class UserFeedManager(models.Manager):    
        def filter(self, *args, **kwargs):
            keywordargs = {}
            for (arg, val) in kwargs.items():
                if '__contains' in arg:
                    contains.append((arg.split('__')[0], val))
                else:
                    keywordargs[arg] = val
    
            result = []
            if len(contains) > 0:
                for entry in super(UserFeedManager, self).filter(*args, **keywordargs):
                    if all(map(lambda (attr, val): val in entry.__getattribute__(attr),
                               contains)):
                        result.append(entry)
            else:
                result = super(UserFeedManager, self).filter(*args, **keywordargs)
    
            return result
    

    本质上,它会构建一个包含 __contains 的参数列表,然后获取整个结果并对其进行过滤以仅保存通过所有条件的结果。

    【讨论】:

      【解决方案4】:
      querySet = Entity.objects.all()
      ids = []
      for i,obj in enumerate(querySet.iterator()):
          str_to_search =obj.name
          if str_to_search.find('blahblah') != -1:
              ids.append(obj.id)
      querySet = querySet.filter(id__in = ids)
      

      【讨论】:

      • 嗨,欢迎来到 SO。在代码的某些部分中包含一些解释可能很有用。另请注意,您正在回答一个相当老的问题,这可能不再相关。
      猜你喜欢
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 2010-12-12
      • 2018-03-04
      相关资源
      最近更新 更多