如何在 Java 中对社交图进行建模

发布于 2024-08-19 08:27:55 字数 179 浏览 5 评论 0原文

非常简单的场景

N 个用户,每个用户可以有 0 .. N - 1 个朋友(他们也是用户)

我如何在 AppEngine 数据存储的 Java 中对此进行建模

考虑

  • 用户 x 和用户 y 的 场景朋友(所以双方都需要在交易中更新自己的状态

Very simple scenario

N users, each user can have 0 .. N - 1 friends (who are also users)

How can I model this in Java for AppEngine data store

Scenario to consider

  • user x and user y become friends (so both need update their own status, in a transaction

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

大海や 2024-08-26 08:27:55

我们将用户关系建模为一个简单的 UserRelation 实体:

class UserRelation {
  User _from;
  User _to;
  RelationState _state;
}

其中 RelationState 是一个枚举,描述状态(通常,不仅仅是友谊)

enum RelationState {
  BLOCKED, NONE, PENDING_FRIEND, FRIEND;
}

实际上,我们还使用此枚举进行授权,例如在用户配置文件上。

enum RelationState implements IRole {
  BLOCKED, NONE(BLOCKED), PENDING_FRIEND(NONE), FRIEND(PENDING_FRIEND);

  private final List<IRole> _impliedRoles;
  private final List<String> _roleStrings;

  private RelationState(final IRole... impliedRoles) {
    HashSet<IRole> set = new HashSet<IRole>();
    for (final IRole impliedRole : impliedRoles) {
      set.add(impliedRole);
      set.addAll(impliedRole.getImpliedRoles());
    }
    _impliedRoles = Collections.unmodifiableList(new ArrayList<IRole>(set));

    ArrayList<String> list = new ArrayList<String>(getImpliedRoles().size() + 1);
    list.add(getName());
    for (final IRole implied : getImpliedRoles()) {
      list.add(implied.getName());
    }
    _roleStrings = Collections.unmodifiableList(list);
  }

  public List<IRole> getImpliedRoles() {
    return _impliedRoles;
  }

  public String getName() {
    return name();
  }

  public boolean hasRole(final IRole role) {
    return this == role || _impliedRoles.contains(role);
  }

  public List<String> getRoleStrings() {
    return _roleStrings;
  }
}

public interface IRole {
  public List<? extends IRole> getImpliedRoles();
  public String getName();
  public boolean hasRole(final IRole role);
  public List<String> getRoleStrings();
}

最简单的方法是为每个(对称)关系(例如,在 facebook 上使用的友谊)设置两个对象,为非对称关系(例如,在 twitter 上使用的关注者或阻止的用户)设置一个对象。虽然这首先看起来像是开销,但使用两个对象肯定会简化查询。

我认为 AppEngine 部分本身应该非常简单。

We've modeled user relations as a simple UserRelation entity:

class UserRelation {
  User _from;
  User _to;
  RelationState _state;
}

Where RelationState is an enum, describing states (normally, there is more than friendship)

enum RelationState {
  BLOCKED, NONE, PENDING_FRIEND, FRIEND;
}

Actually, we also use this enum for authorizaton, e.g. on user profiles.

enum RelationState implements IRole {
  BLOCKED, NONE(BLOCKED), PENDING_FRIEND(NONE), FRIEND(PENDING_FRIEND);

  private final List<IRole> _impliedRoles;
  private final List<String> _roleStrings;

  private RelationState(final IRole... impliedRoles) {
    HashSet<IRole> set = new HashSet<IRole>();
    for (final IRole impliedRole : impliedRoles) {
      set.add(impliedRole);
      set.addAll(impliedRole.getImpliedRoles());
    }
    _impliedRoles = Collections.unmodifiableList(new ArrayList<IRole>(set));

    ArrayList<String> list = new ArrayList<String>(getImpliedRoles().size() + 1);
    list.add(getName());
    for (final IRole implied : getImpliedRoles()) {
      list.add(implied.getName());
    }
    _roleStrings = Collections.unmodifiableList(list);
  }

  public List<IRole> getImpliedRoles() {
    return _impliedRoles;
  }

  public String getName() {
    return name();
  }

  public boolean hasRole(final IRole role) {
    return this == role || _impliedRoles.contains(role);
  }

  public List<String> getRoleStrings() {
    return _roleStrings;
  }
}

public interface IRole {
  public List<? extends IRole> getImpliedRoles();
  public String getName();
  public boolean hasRole(final IRole role);
  public List<String> getRoleStrings();
}

It's easiest to have two objects for each (symmetric) relationship (e.g. friendship as used on facebook) and only a single object for non-symmetric relationships (e.g. followers as used on twitter or blocked users). While this might look like overhead in the first place, using two objects certainly simplifies querying.

I think the AppEngine part itself should then be pretty straight forward.

轮廓§ 2024-08-26 08:27:55

考虑使用只有两个外键的 Friendship 表:user1user2。该表中的条目模拟了两个用户之间的社交联系。您甚至可以添加更多列来描述此社交关系的类型

(或考虑 sfussenegger 的答案;)相同的想法但更好的演示)

Consider using a Friendship table with just two foreign keys, user1 and user2. An entry in this table models an social connection between two users. You could even add more columns to describe the type of this social relation.

(or consider sfussenegger's answer ;) same idea but better presentation)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文