2017-06-22 153 views
6

我有我想使用3种不同语言搜索的文档。由于我可以有多个具有相同名称/类型的字段,因此以下文档结构可以工作(这是一个简化示例)。App Engine搜索API(文档搜索) - 多种语言

document = search.Document(
    fields=[ 
     search.TextField(
     name="name", 
     language="en", 
     value="dog"), 
     search.TextField(
     name="name", 
     language="es", 
     value="perro"), 
     search.TextField(
     name="name", 
     language="fr", 
     value="chien") 
    ] 
) 
    index = search.Index("my_index") 
    index.put(document) 

指定语言可帮助Google标记TextField的值。

以下查询所有的工作,每区选出一个结果:

print index.search("name: dog") 
print index.search("name: perro") 
print index.search("name: chien") 

这里是我的问题:我可以限制与特定的语言搜索只定位领域?

目的是为了避免出现假阳性结果。由于每种语言都使用阿拉伯字母,因此有可能执行西班牙语全文搜索的人可能会看到英语结果不相关。

谢谢。

+0

调用谷歌翻译API的语言检测并在查询中使用结果:'get_index(lang-detected).search(query)'或翻译searc h术语存储数据语言并根据翻译结果进行搜索 – hadi

回答

2

您可以使用facets将字段添加到实际不出现在文档中的文档(元数据)。这些将指示文档中出现的语言。

文档插入:

index = search.Index("my_index") 
    document = search.Document(
     fields=[ 
      search.TextField(
      name="name", 
      language="en", 
      value="dog"), 
      search.TextField(
      name="name", 
      language="es", 
      value="perro"), 
      search.TextField(
      name="name", 
      language="fr", 
      value="chien") 
     ], 
     facets=[ 
      search.AtomFacet(name='lang', value='en'), 
      search.AtomFacet(name='lang', value='es'), 
      search.AtomFacet(name='lang', value='fr'), 
     ], 
    ) 
    index.put(document) 
    document = search.Document(
     fields=[ 
      search.TextField(
      name="name", 
      language="es", 
      value="gato"), 
      search.TextField(
      name="name", 
      language="fr", 
      value="chat") 
     ], 
     facets=[ 
      # no english in this document so leave out lang='en' 
      search.AtomFacet(name='lang', value='es'), 
      search.AtomFacet(name='lang', value='fr'), 
     ], 
    ) 
    index.put(document) 

查询:

index = search.Index("my_index") 
query = search.Query(
    '', # query all documents, cats and dogs. 
    # filter docs by language facet 
    facet_refinements=[ 
     search.FacetRefinement('lang', value='en'), 
    ]) 

results = index.search(query) 
for doc in results: 
    result = {} 
    for f in doc.fields: 
     # filter fields by language 
     if f.language == 'en': 
      result[f.name] = f.value 
    print result 

应打印{u'name': u'dog'}

注意,虽然我们只获取文件是在他们的英语,我们还是要过滤掉领域在这些文件中的其他语言。这就是为什么我们遍历字段只添加英文到result

如果您想了解更多有关多面搜索的更一般用例,请点击这里this answer给出一个不错的主意。

+0

原来,您需要使用FacetRefinements而不是FacetRequests。前者是通过方面来选择文档,后者只给你关于哪些方面可用的信息。 –

+0

document = search.Document( doc_id = str(“1”), fields = [ 搜索。TextField的(语言= “EN”,名字= “姓名”,值= “1”), search.TextField(语言= “ES”,名字= “姓名”,值= “UNO”) ]) 索引。 (文档) document = search.Document( doc_id = str(“2”), fields = Search.TextField(language =“en”,name =“name”,value =“uno”), search.TextField(language =“es”,name =“name”,value =“one”) ]) index.put(document) index.search(search.Query( “name:one”, facet_refinements = [ search.FacetRefinement(“郎”,值=“EN”) )) – user326502

+0

上面的代码是相当严重的,但SO不会让我˚F ormat它在评论中。这是FacetRefinement返回零结果的情况,尽管有匹配。你知道为什么吗? – user326502

2

您可以为每种语言使用单独的索引。

定义一个效用函数解决的正确索引对于给定的语言:

def get_index(lang): 
    return search.Index("my_index_{}".format(lang)) 

插入文件:

document = search.Document(
    fields=[ 
     search.TextField(
     name="name", 
     language="en", 
     value="dog"), 
    ]) 

get_index('en').put(document) 

document = search.Document(
    fields=[ 
     search.TextField(
     name="name", 
     language="fr", 
     value="chien") 
    ]) 

get_index('fr').put(document) 

查询的语言:

query = search.Query(
    'name: chien') 

results = get_index('fr').search(query) 

for doc in results: 
    print doc 
+0

我采用了类似的方法,对每种语言使用单独的字段,然后将语言代码附加到搜索字段名称。这是我的后备方法,但我希望能在这里找到更好的解决方案。 – user326502