Mongoid學習

1. 安裝mongoid

在Rails 配置文件Gemfile中,做如下配置


  gem 'mongoid', '~> 5.0.0'

2. 配置文件

執行 rails g mongoid:config 即可生成
myapp/config/mongoid.yml

在該配置文件中,你可以定制自己的配置


development:
 clients:
   default:
     database: mongoid
     hosts:
       - localhost:27017

還需要在 application.rb 文件中做如下配置,設置關系映射使用mongoid


  config.generators do |g|
    g.orm :mongoid
  end

3. Document

Document可以作為集合存儲,也可以鑲嵌到其他的Document中

Documents can be stored in their own collections in the database
or can be embedded in other Documents n levels deep.

4. 存儲


  class Person
    include Mongoid::Document
  end

你可以在類級別更改該Person的存儲位置


  class Person
    include Mongoid::Document
    store_in collection: "citizens", database: "other", client: "secondary"
  end

5. Fields

通過網絡傳輸的String 參數,
Mongoid 提供了一個簡單的機制來將他們轉換成正確合適的類型,
通過定field定義


  class Person
    include Mongoid::Document
    field :first_name, type: String
    field :middle_name, type: String
    field :last_name, type: String
  end

除了String, 還有如下類型:


  Array
  BigDecimal
  Boolean
  Date
  DateTime
  Float
  Hash
  Integer
  BSON::ObjectId
  BSON::Binary
  Range
  Regexp
  String
  Symbol
  Time
  TimeWithZone

6. 訪問設置Field

如果field已經定義,Mongoid提供了多種方式來訪問field


  # Get the value of the first_name field
  person.first_name
  person[:first_name]
  person.read_attribute(:first_name)


  # Set the value for the first_name field
  person.first_name = "Jean"
  person[:first_name] = "Jean"
  person.write_attribute(:first_name, "Jean")

通過以下途徑訪問設置多值


  # Get the field values as a hash.
  person.attributes

  # Set the field values in the document.
  Person.new(first_name: "Jean-Baptiste", middle_name: "Emmanuel")
  person.attributes = { first_name: "Jean-Baptiste", middle_name: "Emmanuel" }
  person.write_attributes(
    first_name: "Jean-Baptiste",
    middle_name: "Emmanuel"
  )


存儲設置Hash Field


class Person
  include Mongoid::Document
  field :first_name
  field :url, type: Hash

  # will update the fields properly and save the values
  def set_vals
    self.first_name = 'Daniel'
    self.url = {'home_page' => 'http://www.homepage.com'}
    save
  end

end

存儲到數據庫具體形式如下:


  { "_id" : ObjectId("56877d3408d67e50cb000008"),  "first_name" : "zhangsan", "url" : { "home_page" : "http://www.homepage.com" }, "updated_at" : ISODate("2016-01-02T07:33:34.721Z"), "created_at" : ISODate("2016-01-02T07:33:34.721Z") }

7. 設置默認值


  class Person
    include Mongoid::Document
    field :blood_alcohol_level, type: Float, default: 0.40
    field :last_drink, type: Time, default: ->{ 10.minutes.ago }
  end

或者根據Object的狀態來設置默認值


  field :intoxicated_at, type: Time, default: ->{ new_record? ? 2.hours.ago : Time.now }

8. Custom Ids

如果你不想使用BSON::ObjectID ids, 你可以覆蓋 Mongoid`s _id
值,只要你喜歡樂意。


  class Band
    include Mongoid::Document
    field :name, type: String
    field :_id, type: String, default: ->{ name }
  end

9. Dynamic Fields

默認情況Mongoid 不支持 dynamic fields,
你可以告訴mongoid支持dynamic fields 通過配置


 including Mongoid::Attributes::Dynamic in model


  class Person
    include Mongoid::Document
    include Mongoid::Attributes::Dynamic
  end

關于dynamic fields 有兩個重要的規則

  1. 如果attribute 在document中存在,Mongoid 提供標準的getter 和 setter

  # Set the person's gender to male.
  person[:gender] = "Male"
  person.gender = "Male"

  # Get the person's gender.
  person.gender

  1. 如果attribute 在document中不存在,Mongoid不提供 getter 和
    setter,并且會強制拋出異常。在這種情況下,你可以使用
    [] 或 []= 或 read_attribute 或 write_attribute 方法

  >> bb = Teacher.new
  => #<Teacher _id: 5688bdb908d67e29cd000004, >
  >> bb[:gender]
  => nil
  >> bb.read_attribute(:gender)
  => nil
  >> bb[:gender] = "Male"
  => "Male"
  >> bb.write_attribute(:gender, "Female")
  => "Female"
  >> bb[:gender]
  => "Female"
  >> bb.gender
  => "Female"
  >> bb.name
  NoMethodError: undefined method `name' for #<Teacher _id: 5688bdb908d67e29cd000004, gender: "Female">

10. 查看attribute changes變化


  class Person
    include Mongoid::Document
    field :name, type: String
  end

  person = Person.first
  person.name = "Alan Garner"

  # Check to see if the document has changed.
  person.changed? #=> true

  # Get an array of the names of the changed fields.
  person.changed #=> [ :name ]

  # Get a hash of the old and changed values for each field.
  person.changes #=> { "name" => [ "Alan Parsons", "Alan Garner" ] }

  # Check if a specific field has changed.
  person.name_changed? #=> true

  # Get the changes for a specific field.
  person.name_change #=> [ "Alan Parsons", "Alan Garner" ]

  # Get the previous value for a field.
  person.name_was #=> "Alan Parsons"

11. 重置changes


  person = Person.first
  person.name = "Alan Garner"

  # Reset the changed name back to the original
  person.reset_name!
  person.name #=> "Alan Parsons"

12. 關于changes 和 save的關系

如果changes沒有任何變更,Mongoid 也不會變更數據庫的內容 通過Model#save
方法


  >> bb = Student.find(BSON::ObjectId("56877eae08d67e50cb00000b"))
  MONGODB | localhost:27017 | funds_development.find | STARTED | {"find"=>"students", "filter"=>{"_id"=>BSON::ObjectId('56877eae08d67e50cb00000b')}}
  MONGODB | localhost:27017 | funds_development.find | SUCCEEDED | 0.010262s
  => #<Student _id: 56877eae08d67e50cb00000b, created_at: 2016-01-02 07:39:26 UTC, updated_at: 2016-01-02 07:43:52 UTC, name: "jean", url: {"home_page"=>"www.jd.com"}, last_drink: 2016-01-02 07:29:26 UTC, intoxicated_at: 2016-01-02 05:39:26 UTC>
  >> bb.attributes
  => {"_id"=>BSON::ObjectId('56877eae08d67e50cb00000b'), "name"=>"jean", "url"=>{"home_page"=>"www.jd.com"}, "last_drink"=>2016-01-02 07:29:26 UTC, "intoxicated_at"=>2016-01-02 05:39:26 UTC, "updated_at"=>2016-01-02 07:43:52 UTC, "created_at"=>2016-01-02 07:39:26 UTC}
  >> bb.updated_at
  => Sat, 02 Jan 2016 07:43:52 UTC +00:00
  >> bb.updated_at.to_s(:db)
  => "2016-01-02 07:43:52"
  >> bb.save
  => true
  >> Student.find(BSON::ObjectId("56877eae08d67e50cb00000b")).updated_at.to_s(:db)
  MONGODB | localhost:27017 | funds_development.find | STARTED | {"find"=>"students", "filter"=>{"_id"=>BSON::ObjectId('56877eae08d67e50cb00000b')}}
  MONGODB | localhost:27017 | funds_development.find | SUCCEEDED | 0.0007s
  => "2016-01-02 07:43:52"

13. Readonly Attributes

你可以設置某些field為只讀,創建之后便不能修改。


  class Band
    include Mongoid::Document
    field :name, type: String
    field :origin, type: String

    attr_readonly :name, :origin
  end

  band = Band.create(name: "Placebo")
  band.update_attributes(name: "Tool") # Filters out the name change.

如果你強制更新或修改某一個只讀的field,便會拋出異常。


  band.update_attribute(:name, "Tool") # Raises the error.
  band.remove_attribute(:name) # Raises the error.

14. 繼承

Document 繼承來自與他們的fields, relations, validations 或者是
scopes 來自于他們的child documents.


  class Canvas
    include Mongoid::Document
    field :name, type: String
    embeds_many :shapes
  end

  class Browser < Canvas
    field :version, type: Integer
    scope :recent, where(:version.gt => 3)
  end

  class Firefox < Browser
  end

  class Shape
    include Mongoid::Document
    field :x, type: Integer
    field :y, type: Integer
    embedded_in :canvas
  end

  class Circle < Shape
    field :radius, type: Float
  end

  class Rectangle < Shape
    field :width, type: Float
    field :height, type: Float
  end

**Querying Subclasses**

  # Returns Canvas documents and subclasses
  Canvas.where(name: "Paper")
  # Returns only Firefox documents
  Firefox.where(name: "Window 1")

**Associations**

```

  firefox = Firefox.new
  # Builds a Shape object
  firefox.shapes.build({ x: 0, y: 0 })
  # Builds a Circle object
  firefox.shapes.build({ x: 0, y: 0 }, Circle)
  # Creates a Rectangle object
  firefox.shapes.create({ x: 0, y: 0 }, Rectangle)

  rect = Rectangle.new(width: 100, height: 200)
  firefox.shapes

```

15. 時間戳

Mongoid::Timestamps 提供了 created_at 和 updated_at field.


  class Person
    include Mongoid::Document
    include Mongoid::Timestamps
  end

或者你可以使用特殊的時間戳,creation 或 modification


  class Person
    include Mongoid::Document
    include Mongoid::Timestamps::Created
  end

  class Post
    include Mongoid::Document
    include Mongoid::Timestamps::Updated
  end

16. Persistence

Mongoid supports all expected CRUD operations for those familiar with
other Ruby mappers like Active Record or Data Mapper. What
distinguished Mongoid from other mappers for MongoDB is that the
general persistence operations perform atomic updated on only the
fields that have changed instead of writing the entire document to
the database each time.


Person.create(
first_name: "Heinrich",
last_name: "Heine"
)

Person.create([
{ first_name: "Heinrich", last_name: "Heine" },
{ first_name: "Willy", last_name: "Brandt" }
])

person.save
person.save(validate: false)

person.update_attributes!(
first_name: "Jean",
last_name: "Zorg"
)

person.update_attribute(:first_name, "Jean")


特殊的field用法

Model#upsert

如果這個attribute 存在,則覆蓋,如果沒有則插入。


  person = Person.new(
    first_name: "Heinrich",
    last_name: "Heine"
  )
  person.upsert

Model#touch

更新updated_at 時間戳,也可以根據配置級聯更改關聯關系。
該方法跳過validation 和 callbacks


  person.touch
  person.touch(:audited_at)

Model#delete

刪除數據,并且沒有任何回調

Model#destory

刪除數據,并且執行回調

17. Atomic

當執行這些原子操作時,沒有回調,沒有校驗


  person.add_to_set(aliases: "Bond")   # $addToSet
  person.bit(age: { and: 10, or: 12 }) # $bit
  person.inc(age: 1)                   # $inc
  person.pop(aliases: 1)               # $pop
  person.pull(aliases: "Bond")         # $pull

18. 查詢

查詢 DSL


  Band.where(name: "Depeche Mode")
  Band.
    where(:founded.gte => "1980-1-1").
    in(name: [ "Tool", "Deftones" ]).
    union.
    in(name: [ "Melvins" ])

Additional Query Methods

操作 例子
操作 例子
---- ----
Criteria#count
count 查詢會涉及到數據庫查詢
Band.count
Band.where(name: "Photek").count
Criteria#distinct
獲取單一field
Band.distinct(:name)
Band.where(:fans.gt => 100000).distinct(:name)
Criteria#each
迭代獲取匹配數據
Band.where(members: 1).each do
Criteria#exists?
判斷獲取數據是否存在
Band.exists?
Band.where(name: "Photek").exists?
Criteria#find
獲取一個文檔或多個文檔通過ids,如果沒有找到就會報錯
Band.find("4baa56f1230048567300485c")
Band.find( "4baa56f1230048567300485c", "4baa56f1230048567300485d")
Criteria#find_by
根據某一個field 來獲取文檔
Band.find_by(name: "Photek")
Criteria#find_or_create_by
根據attributes來查找文檔,如果沒有找到,就創建該文檔
Band.where(:likes.gt => 10).find_or_create_by(name: "Photek")
Criteria#find_or_initialize_by
查找文檔,若沒找到,則初始化
Band.where(:likes.gt => 10).find_or_initialize_by(name: "Photek")
Criteria#first_or_create
根據attributes 查找第一個文檔,如果不存在,就創建
Band.where(name: "Photek").first_or_create
Criteria#first_or_initialize
根據attributes 查找第一個文檔,如果不存在,就初始化
Band.where(name: "Photek").first_or_initialize
Criteria#pluck
獲取不為nil的值
Band.all.pluck(:name)

19. Eager Loading

Eager loaded is supported on all relations with the exception of polymorphic belongs_to associations.


  class Band
    include Mongoid::Document
    has_many :albums
  end

  class Album
    include Mongoid::Document
    belongs_to :band
  end

  Band.includes(:albums).each do |band|
    p band.albums.first.name # Does not hit the database again.
  end

20. 關聯關系


>> p = Person.find('5687839408d67e50cb00000f')
MONGODB | localhost:27017 | funds_development.find | STARTED | {"find"=>"people", "filter"=>{"_id"=>BSON::ObjectId('5687839408d67e50cb00000f')}}
MONGODB | localhost:27017 | funds_development.find | SUCCEEDED | 0.005945s
=> #<Person _id: 5687839408d67e50cb00000f, first_name: "zhang", middle_name: "san", last_name: "bb">
>> p.addresses
=> [#<Address _id: 568783ce08d67e50cb000010, name: "one", addressable_type: nil, addressable_id: nil>, #<Address _id: 568783ce08d67e50cb000011, name: "two", addressable_type: nil, addressable_id: nil>]
>> p.addresses.target
=> [#<Address _id: 568783ce08d67e50cb000010, name: "one", addressable_type: nil, addressable_id: nil>, #<Address _id: 568783ce08d67e50cb000011, name: "two", addressable_type: nil, addressable_id: nil>]
>> p.addresses.base
=> #<Person _id: 5687839408d67e50cb00000f, first_name: "zhang", middle_name: "san", last_name: "bb">
>> p.addresses.metadata
=> #<Mongoid::Relations::Metadata
autobuild:    false
class_name:   Address
cyclic:       nil
counter_cache:false
dependent:    nil
inverse_of:   nil
key:          addresses
macro:        embeds_many
name:         addresses
order:        nil
polymorphic:  false
relation:     Mongoid::Relations::Embedded::Many
setter:       addresses=>

21. embeds_many 擴展


class Person
  include Mongoid::Document

  field :first_name, type: String
  field :middle_name, type: String
  field :last_name, type: String

  embeds_many :addresses do
    def find_by_name(name)
      where(name: name).first
    end

    def the_one
      @target.select{ |address| address.name == 'one' }
    end
  end
  has_many :posts, autosave: true
end

p.addresses.the_one # return [ address]
p.addresses.find_by_name('aaa') # return address


>> p = Person.find('5687839408d67e50cb00000f')
MONGODB | localhost:27017 | funds_development.find | STARTED | {"find"=>"people", "filter"=>{"_id"=>BSON::ObjectId('5687839408d67e50cb00000f')}}
MONGODB | localhost:27017 | funds_development.find | SUCCEEDED | 0.000462s
=> #<Person _id: 5687839408d67e50cb00000f, first_name: "zhang", middle_name: "san", last_name: "bb">
>> p.addresses
=> [#<Address _id: 568783ce08d67e50cb000010, name: "one", addressable_type: nil, addressable_id: nil>, #<Address _id: 568783ce08d67e50cb000011, name: "two", addressable_type: nil, addressable_id: nil>]
>> p.addresses.the_one
=> [#<Address _id: 568783ce08d67e50cb000010, name: "one", addressable_type: nil, addressable_id: nil>]
>> p.addresses.find_by_name('two')
=> #<Address _id: 568783ce08d67e50cb000011, name: "two", addressable_type: nil, addressable_id: nil>

22. 定制關系的名字

你可以隨意定義關聯關系的名字,但是你需要填寫必要的選項來讓mongoid找到對應
的類。


 class Lush
  include Mongoid::Document
  embeds_one :whiskey, class_name: "Drink", inverse_of: :alcoholic
 end

 class Drink
   include Mongoid::Document
   embedded_in :alcoholic, class_name: "Lush", inverse_of: :whiskey
 end

23. 關聯關系校驗

默認情況下,如下的關聯關系,會存在校驗。
如果需要去掉關聯關系校驗,則可以在定義類的時候,就去除。


  embeds_many
  embeds_one
  has_many
  has_one
  has_and_belongs_to_many


  class Person
    include Mongoid::Document

    embeds_many :addresses, validate: false
    has_many :posts, validate: false
  end

24. embeds_many 與 has_many 的區別

addresses 屬于 embeds_many
posts 屬于 has_many


  class Person
    include Mongoid::Document

    field :first_name, type: String
    field :middle_name, type: String
    field :last_name, type: String

    embeds_many :addresses do
      def find_by_name(name)
        where(name: name).first
      end

      def the_one
        @target.select{ |address| address.name == 'one' }
      end
    end
    has_many :posts, autosave: true
  end

> db.posts.find()
{ "_id" : ObjectId("5687862c08d67e29cd000001"), "name" : "101", "person_id" : ObjectId("5687839408d67e50cb00000f") }

> db.people.find({ "_id": ObjectId("5687839408d67e50cb00000f") })
{ "_id" : ObjectId("5687839408d67e50cb00000f"), "first_name" : "zhang", "middle_name" : "san", "last_name" : "bb", "addresses" : [ { "_id" : ObjectId("568783ce08d67e50cb000010"), "name" : "one" }, { "_id" : ObjectId("568783ce08d67e50cb000011"), "name" : "two" } ] }

由此可見,embeds_many 是嵌入到其他的document中
而has_many 是額外存在于其他的collections 中

25. 多態

一個child document 可以屬于多個parent document,在parent document
中添加 as 選項來告訴Mongoid, 并且在child document中設置 polymorphic
選項。在child選項中,根據這個額外添加的選項,就可以獲取到父類型。

多態存在于 has_and_belongs_to_many 的關系中。


  class Band
    include Mongoid::Document
    embeds_many :photos, as: :photographic
    has_one :address, as: :addressable
  end

  class Photo
    include Mongoid::Document
    embedded_in :photographic, polymorphic: true
  end

26. 級聯回調

如果你想在父類上調用embedded document 的級聯,需要做如下設置


  class Band
    include Mongoid::Document
    embeds_many :albums, cascade_callbacks: true
    embeds_one :label, cascade_callbacks: true
  end

  band.save # Fires all save callbacks on the band, albums, and label.

27. 約束行為

如果關聯關系的一方刪除,可以設置關聯的另一方的關系

:delete: 刪除關系,不會調用什么回調
:destroy: 刪除關系,但是會調用回調函數
:nullify: 使關聯關系的另一方,孤立
:restrict: 如果child不為空,則拋出異常


  class Band
    include Mongoid::Document
    has_many :albums, dependent: :delete
    belongs_to :label, dependent: :nullify
  end

  class Album
    include Mongoid::Document
    belongs_to :band
  end

  class Label
    include Mongoid::Document
    has_many :bands, dependent: :restrict
  end

  label = Label.first
  label.bands.push(Band.first)
  label.delete # Raises an error since bands is not empty.

  Band.first.delete # Will delete all associated albums.


28. 自動保存

Mongoid 和 Active Record 的另一個不同就是,不會自動
保存級聯關系,是為了性能考慮。

鑲嵌的關聯并不需要設置autosave,因為實際上他就是屬于父Object
的一部分。其余的關聯關系,都可以設置 autosave


  class Band
    include Mongoid::Document
    has_many :albums, autosave: true
  end

  band = Band.first
  band.albums.build(name: "101")
  band.save #=> Will save the album as well.

29. 級聯關系中存在的實用方法

在所有關聯關系中都存在 name? 和 has_name? 的方法來校驗relation
是否是空的


  class Band
    include Mongoid::Document
    embeds_one :label
    embeds_many :albums
  end

  band.label?
  band.has_label?
  band.albums?
  band.has_albums?

30. Embeds One

一對一的關聯關系中,使用embeds_one 和 embedded_in 來作為屬性關聯。


  class Band
    include Mongoid::Document
    embeds_one :label
  end

  class Label
    include Mongoid::Document
    field :name, type: String
    embedded_in :band
  end

最后存儲的結果如下


  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
    "label" : {
      "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
      "name" : "Mute",
    }
  }

31. Embeds Many

一對多的嵌入關聯關系,使用 embeds_many 和 embedded_in


  class Band
    include Mongoid::Document
    embeds_many :albums
  end

  class Album
    include Mongoid::Document
    field :name, type: String
    embedded_in :band
  end

最后存儲結果如下:


  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
    "albums" : [
      {
        "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
        "name" : "Violator",
      }
    ]
  }


32. Has One

一對一的關聯關系中,使用 has_one 和 belongs_to


  class Band
    include Mongoid::Document
    has_one :studio
  end

  class Studio
    include Mongoid::Document
    field :name, type: String
    belongs_to :band
  end

最后存儲結果如下


  # The parent band document.
  { "_id" : ObjectId("4d3ed089fb60ab534684b7e9") }

  # The child studio document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f1"),
    "band_id" : ObjectId("4d3ed089fb60ab534684b7e9")
  }

33. Has Many

一對多的關聯關系中,使用has_many 和 belongs_to


  class Band
    include Mongoid::Document
    has_many :members
  end

  class Member
    include Mongoid::Document
    field :name, type: String
    belongs_to :band
  end

最終存儲結果如下


  # The parent band document.
  { "_id" : ObjectId("4d3ed089fb60ab534684b7e9") }

  # A child member document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f1"),
    "band_id" : ObjectId("4d3ed089fb60ab534684b7e9")
  }

34. 多對多的關聯關系

has_and_belongs_to_many

第一種方式


  class Band
    include Mongoid::Document
    has_and_belongs_to_many :tags
  end

  class Tag
    include Mongoid::Document
    field :name, type: String
    has_and_belongs_to_many :bands
  end

第二種方式


  class Band
    include Mongoid::Document
    has_and_belongs_to_many :tags, inverse_of: nil
  end

  class Tag
    include Mongoid::Document
    field :name, type: String
  end

最終存儲結果如下


  # The band document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
    "tag_ids" : [ ObjectId("4d3ed089fb60ab534684b7f2") ]
  }

  # The tag document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f2"),
    "band_ids" : [ ObjectId("4d3ed089fb60ab534684b7e9") ]
  }

35. 回調函數

  • after_initialize
  • after_build
  • before_validation
  • after_validation
  • before_create
  • around_create
  • after_create
  • after_find
  • before_update
  • around_update
  • after_update
  • before_upsert
  • around_upsert
  • after_upsert
  • before_save
  • around_save
  • after_save
  • before_destroy
  • around_destroy
  • after_destroy

36. 索引

給普通的field添加索引


  class Person
    include Mongoid::Document
    field :ssn

    index({ ssn: 1 }, { unique: true, name: "ssn_index" })
  end

給 embedded document 添加索引


  class Person
    include Mongoid::Document
    embeds_many :addresses
    index "addresses.street" => 1
  end

給多個列添加索引


  class Person
    include Mongoid::Document
    field :first_name
    field :last_name

    index({ first_name: 1, last_name: 1 }, { unique: true })
  end

使用下面命令添加索引


  rake db:mongoid:create_indexes

亦提供了刪除所有二級索引的命令


   rake db:mongoid:remove_indexes

ruby-mongoid-tutorial

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,406評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,034評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,413評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,449評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,165評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,559評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,606評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,781評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,327評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,084評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,278評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,849評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,495評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,927評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,172評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,010評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,241評論 2 375

推薦閱讀更多精彩內容

  • 2017年9月18日 星期一 晴 張榮軒媽媽 親子日記第15篇 每個周一的早晨,都是我一周中最焦慮的時候...
    愛意暖人心閱讀 288評論 0 1
  • 張東輝,焦點初級第43期堅持原創分享第35天 天氣放晴,親情融融,姐姐、弟弟和我,三家人,一眾十幾人,抓住假期的尾...
    星悅傳奇閱讀 218評論 0 0
  • 人生之中低谷最多的應該就是20幾歲的年紀吧,沒錢沒房沒車沒愛人甚至工作還是一塌糊涂。但最好的時光也是20幾歲,有夢...
    芳點兒閱讀 440評論 0 1
  • 忙碌勞累的三月已經過去,從四月開始,很多人都希望自己工作順利,家庭幸福,好運常伴。沒錯哦,有這個三個生肖在三月霉運...
    時允舜閱讀 160評論 0 0