Elasticsearch Store' searchable'名单

时间:2015-10-14 15:19:57

标签: elasticsearch

我可以访问Neo4J图表数据库,该数据库存储人员列表以及他们之间的关系(朋友)。我希望实现一个"搜索朋友列表"在给定用户朋友列表中执行搜索的功能。我担心性能,所以我希望使用Elasticsearch实现此搜索;但我不知道如何索引Elasticsearch中Neo4j的用户数据以方便上述查询。一个典型的用例是#34;对于用户x,找到名字以" Mik"开头的朋友。 SearchAPI使用Elasticsearch JavaAPI构建在SpringWeb上。

编辑1:

我所问的与this不同,因为我知道如何使用Elasticsearch河流和其他工具来索引数据。我的问题是寻求建立实现诸如" search_friends_list"等功能的最佳方法。例如,我是否将每个用户的唯一用户标识符用作类型(类似..:9200/users/[username])并将每个给定用户朋友索引到该索引并键入?这样,如果我想搜索用户JackSparrow的朋友列表,我就会执行类似于..:9200/users/JackSparrow/_search?q=search_term的事情。这个例子很有气味,当我系统中的用户数量增加时,可能会导致严重的性能下降。这就是我需要帮助和建议的地方。有哪些方法可以实现这样的解决方案?

编辑2:删除了Neo4J标签,提供了更多信息

映射

{
    "people": {
        "mappings": {
            "friends": {
                "properties": {
                    "firstname": {
                        "type": "string"
                    },
                    "friends": {
                        "type": "string"
                    },
                    "fullname": {
                        "type": "string"
                    },
                    "id": {
                        "type": "long"
                    },
                    "lastname": {
                        "type": "string"
                    },
                    "username": {
                        "type": "string"
                    },
                    "userid": {
                        "type": "string"
                    }
                }
            }
        }
    }
}

数据

{
    "_index": "people",
    "_type": "friends",
    "_id": "24482ba5-06fa-2f58-2560-4b8fa5e3d1a7",
    "_score": 11.5473,
    "_source": {
        "firstname": "Carl",
        "id": 4735,
        "fullname": "Carl Platt",
        "userid": "24482ba5-06fa-2f58-2560-4b8fa5e3d1a7",
        "friends": [
            "8248f90b-3c30-b60a-d64f-ced55304fcb0",
            "8b4a0960-f792-87d5-be4d-17a53963c29e",
            "904a4d6f-c7ce-8ae3-edf2-e0ac6bc69885",
            "934e0e4b-2b20-b7b1-c092-1eb22e3e92bd",
            "954e1500-7f74-468e-b611-cd35382d9aa6",
            "994cacfc-3a76-c77a-adec-b50804933490",
            "a942b4b7-cdcc-8653-ef73-a6000dbd418c",
            ...

查询

{
  "query": {
    "filtered": {
      "query": {
        "query_string": {
          "default_field": "firstname",
          "query": "Amu*"          
        }
      },
      "filter": {
        "terms": {
          "friends": {
            "index": "people",
            "type": "friends",
            "id": "24482ba5-06fa-2f58-2560-4b8fa5e3d1a7",            
            "path": "userid"
          }
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:2)

在官方文档中,有关Twitter用户及其推文的类似示例,以说明terms lookup mechanism,它可以很好地完成您正在寻找的内容。

我们的想法是拥有一个包含users文档的user索引。表示用户的每个文档都将具有包含其朋友的ID的数组属性。让我们创建users索引的简单版本:

curl -XPUT localhost:9200/users -d '{
  "mappings": {
    "user": {
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "friends": {
          "type": "integer"
        }
      }
    }
  }
}'

现在让我们为一些示例数据编制索引,其中用户1与所有其他用户是朋友,但是4(Mike):

curl -XPOST localhost:9200/users/user/_bulk -d '
{"index":{"_id":1}}
{"id": 1, "name": "John", "friends": [2,3,5]}
{"index":{"_id":2}}
{"id": 2, "name": "Mikil", "friends": [1,3]}
{"index":{"_id":3}}
{"id": 3, "name": "Maxim", "friends": [1,2]}
{"index":{"_id":4}}
{"id": 4, "name": "Mike", "friends": [5]}
{"index":{"_id":5}}
{"id": 5, "name": "Philip", "friends": [1,4]}
'

所以我重申了一个典型的用例,即"对于用户x,找到名字以" Mik" 开头的朋友。通过这样的设置,可以使用以下查询来完成:

curl -XPOST localhost:9200/users/user/_search -d '{
  "query": {
    "filtered": {
      "query": {
        "query_string": {
          "default_field": "name",
          "query": "mik*"         <--- only friends whose name starts with "mik" 
        }
      },
      "filter": {
        "terms": {
          "friends": {
            "index": "users",
            "type": "user",
            "id": "1",            <--- only friends of user 1
            "path": "id"
          }
        }
      }
    }
  }
}'

结果只包含用户2(Mikil)而不包含4(Mike)。 QED。