1

我在 ES 索引中保存用户关系

IE

{'id' => 1, 'User_id_1' => '2001', 'relation' => '朋友', 'User_id_2' => '1002'} {'id' => 2, 'User_id_1' => '2002 ', '关系' => '朋友', 'User_id_2' => '1002'}

{'id' => 3, 'User_id_1' => '2002', 'relation' => '朋友', 'User_id_2' => '1001'} {'id' => 4, 'User_id_1' => '2003 ', '关系' => '朋友', 'User_id_2' => '1003'}

不,我想得到拥有最多朋友的 user_id_2,

在上述情况下,它的 1002 是 2001,而 2002 是它的朋友。(计数 = 2)

我只是无法弄清楚查询

谢谢。

编辑:

正如@imotov 所建议的那样,术语方面是非常好的选择,但是

我遇到的问题是 2 个索引

第一个索引用于保存主要文档,第二个索引用于保存关系

现在的问题是

假设我的主索引中有 100 个 USER Docs,其中只有 50 个建立了关系,所以我的关系索引中只有 50 个 USER Docs

因此,当我实现“术语方面”时,它会对结果进行排序并给出我想要的正确输出,但我错过了那些还没有任何关系的剩余 50 个用户,我需要在 50 个排序后的最终输出中使用它们用户。

4

1 回答 1

1

首先,我们需要确保 ES 中保存的关系是唯一的。可以通过将任意 id 替换为由 user_id_1、relation 和 user_id_2 构造的 id 来完成。我们还需要确保 user_ids 的分析器不会产生多个令牌。如果 id 是字符串,它们必须被索引 not_analyzed。在满足这两个条件的情况下,我们可以简单地对由relation:friend限制的结果列表中的字段user_id_2使用terms facet查询。此查询将检索按索引中出现次数排序的前 user_id_2 id。总而言之,它可能看起来像这样:

curl -XPUT http://localhost:9200/relationships -d '{
    "mappings" : {
        "relation" : {
            "_source" : {"enabled" : false },
            "properties" : {
                "user_id_1": { "type": "string", "index" : "not_analyzed"},
                "relation": { "type": "string", "index" : "not_analyzed"},
                "user_id_2": { "type": "string", "index" : "not_analyzed"}
            }
        }
    }
}'

curl -XPUT http://localhost:9200/relationships/relation/2001-friend-1002 -d '{"user_id_1": "2001", "relation":"friend", "user_id_2": "1002"}'
curl -XPUT http://localhost:9200/relationships/relation/2002-friend-1002 -d '{"user_id_1": "2002", "relation":"friend", "user_id_2": "1002"}'
curl -XPUT http://localhost:9200/relationships/relation/2002-friend-1001 -d '{"user_id_1": "2002", "relation":"friend", "user_id_2": "1001"}'
curl -XPUT http://localhost:9200/relationships/relation/2003-friend-1003 -d '{"user_id_1": "2003", "relation":"friend", "user_id_2": "1003"}'
curl -XPOST http://localhost:9200/relationships/_refresh
echo


curl -XGET 'http://localhost:9200/relationships/relation/_search?pretty=true&search_type=count' -d '{
  "query": {
    "term" : {
      "relation" : "friend"
    }
  },
  "facets" : {
      "popular" : {
          "terms" : {
              "field" : "user_id_2"
          }
      }
  }
}'

请注意,由于构面计算的分布式特性,如果使用多个分片,构面查询报告的计数可能低于实际记录数。请参阅弹性搜索问题 1832

编辑:

编辑后的问题有两种解决方案。一种解决方案是在两个字段上使用 facet:

curl -XPUT http://localhost:9200/relationships -d '{
    "mappings" : {
        "relation" : {
            "_source" : {"enabled" : false },
            "properties" : {
                "user_id_1": { "type": "string", "index" : "not_analyzed"},
                "relation": { "type": "string", "index" : "not_analyzed"},
                "user_id_2": { "type": "string", "index" : "not_analyzed"}
            }
        }
    }
}'
curl -XPUT http://localhost:9200/users -d '{
    "mappings" : {
        "user" : {
            "_source" : {"enabled" : false },
            "properties" : {
                "user_id": { "type": "string", "index" : "not_analyzed"}
            }
        }
    }
}'

curl -XPUT http://localhost:9200/users/user/1001 -d '{"user_id": 1001}'
curl -XPUT http://localhost:9200/users/user/1002 -d '{"user_id": 1002}'
curl -XPUT http://localhost:9200/users/user/1003 -d '{"user_id": 1003}'
curl -XPUT http://localhost:9200/users/user/1004 -d '{"user_id": 1004}'
curl -XPUT http://localhost:9200/users/user/1005 -d '{"user_id": 1005}'
curl -XPUT http://localhost:9200/relationships/relation/2001-friend-1002 -d '{"user_id_1": "2001", "relation":"friend", "user_id_2": "1002"}'
curl -XPUT http://localhost:9200/relationships/relation/2002-friend-1002 -d '{"user_id_1": "2002", "relation":"friend", "user_id_2": "1002"}'
curl -XPUT http://localhost:9200/relationships/relation/2002-friend-1001 -d '{"user_id_1": "2002", "relation":"friend", "user_id_2": "1001"}'
curl -XPUT http://localhost:9200/relationships/relation/2003-friend-1003 -d '{"user_id_1": "2003", "relation":"friend", "user_id_2": "1003"}'
curl -XPOST http://localhost:9200/relationships/_refresh
curl -XPOST http://localhost:9200/users/_refresh
echo


curl -XGET 'http://localhost:9200/relationships,users/_search?pretty=true&search_type=count' -d '{
    "query": {
        "indices" : {
          "indices" : ["relationships"],
          "query" : {
              "filtered" : {
                  "query" : {
                      "term" : {
                          "relation" : "friend"
                      }
                  },
                  "filter" : {
                      "type" : {
                          "value" : "relation"
                      }
                  }
              }
          },
          "no_match_query" : {
              "filtered" : {
                  "query" : {
                      "match_all" : { }
                  },
                  "filter" : {
                      "type" : {
                          "value" : "user"
                      }
                  }
              }

          }      
        }
    },
    "facets" : {
        "popular" : {
          "terms" : {
              "fields" : ["user_id", "user_id_2"]
          }
        }
    }
}'

另一种解决方案是在创建用户时为每个用户的关系索引添加“自我”关系。我更喜欢第二种解决方案,因为它似乎不那么复杂。

于 2012-08-11T14:14:02.950 回答